def merge(left, right): # TODO: Needs testing result = [] for item in left: smaller_items, right = split_list_by_pivot(right, item) result = result + smaller_items + [item] if right: result = result + right return result
def kth_by_quickselect(unsorted_list, k): pivot = random.choice(unsorted_list) smaller, larger = split_list_by_pivot(unsorted_list, pivot) values_before_pivot = len(smaller) if values_before_pivot == k - 1: return pivot elif values_before_pivot > k - 1: return kth_by_quickselect(smaller, k) else: return kth_by_quickselect(larger, k - values_before_pivot - 1)
def kth_by_mom(unsorted_list, k): if len(unsorted_list) <= CHUNK_SIZE: return get_kth(unsorted_list, k) chunks = split_into_chunks(unsorted_list, CHUNK_SIZE) medians_list = [] for chunk in chunks: median_chunk = get_median(chunk) medians_list.append(median_chunk) size = len(medians_list) mom = kth_by_mom(medians_list, size / 2 + (size % 2)) smaller, larger = split_list_by_pivot(unsorted_list, mom) values_before_mom = len(smaller) if values_before_mom == (k - 1): return mom elif values_before_mom > (k - 1): return kth_by_mom(smaller, k) else: return kth_by_mom(larger, k - values_before_mom - 1)