def best_case_quicksort(A, p, r): if p < r: n = r - p + 1 select(A, p, r, (n + 1) // 2) q = (p + r) // 2 best_case_quicksort(A, p, q - 1) best_case_quicksort(A, q + 1, r)
def median_neighbors(A, k): n = A.length m = math.floor((n + 1) / 2) leftmost = select(A, 1, n, m - math.floor((k - 1) / 2)) rightmost = select(A, 1, n, m + math.ceil((k - 1) / 2)) N = set() for i in between(1, n): if leftmost <= A[i] <= rightmost: N.add(A[i]) return N
def quantiles(A, p, r, k): if k == 1: return set() n = r - p + 1 q1 = p + math.floor(math.floor(k / 2) * (n / k)) q2 = p + math.floor(math.ceil(k / 2) * (n / k)) select(A, p, r, q1 - p + 1) if q1 != q2: select(A, q1 + 1, r, q2 - q1) L = quantiles(A, p, q1 - 1, math.floor(k / 2)) R = quantiles(A, q2 + 1, r, math.floor(k / 2)) return L | {A[q1], A[q2]} | R
def median_nearest(A, k): n = A.length x = select(A, 1, n, math.floor((n + 1) / 2)) dist = Array.indexed(1, n) for i in between(1, n): dist[i] = abs(A[i] - x) y = select(dist, 1, n, k) N = set() for i in between(1, n): if abs(A[i] - x) <= y: N.add(A[i]) if len(N) == k + 1: N.remove(x + y) return N
def _effective_fractional_knapsack(items, K, W): n = items.length if n == 0: return K unit_values = Array([item.value / item.weight for item in items]) m = select(unit_values, 1, n, math.floor((n + 1) / 2)) G = Array([item for item in items if item.value / item.weight > m]) E = Array([item for item in items if item.value / item.weight == m]) L = Array([item for item in items if item.value / item.weight < m]) w_G = sum([item.weight for item in G]) w_E = sum([item.weight for item in E]) if w_G >= W: return _effective_fractional_knapsack(G, K, W) for item in G: K[item.id] = item.weight weight_sum = w_G for item in E: if weight_sum + item.weight > W: K[item.id] = W - weight_sum break K[item.id] = item.weight weight_sum += item.weight if w_G + w_E >= W: return K else: return _effective_fractional_knapsack(L, K, W - w_G - w_E)
def test_select(self): array, elements = get_random_array() i = random.randint(1, array.length) actual_order_statistic = select(array, 1, array.length, i) expected_order_statistic = sorted(elements)[i - 1] assert_that(actual_order_statistic, is_(equal_to(expected_order_statistic)))
def delete_larger_half(S): A = _transform_to_array(S) M = select(A, 1, A.length, (A.length + 1) // 2) size = A.length x = S.head while x is not None: if x.key > M: list_delete(S, x) size -= 1 x = x.next x = S.head while size > A.length // 2: if x.key == M: list_delete(S, x) size -= 1 x = x.next
def _select_with_cascaded_swaps(B, m, p, r, i): n = r - p + 1 if n == 1: return p fives = [Array(B.elements[k:min(k + 5, r)]) for k in range(p - 1, r, 5)] for group in fives: insertion_sort(group) medians = Array([group[(group.length + 1) // 2] for group in fives]) x = select(medians, 1, medians.length, (medians.length + 1) // 2) q = _partition_around_with_cascaded_swaps(B, m, p, r, x) k = q - p + 1 if i == k: return q elif i < k: return _select_with_cascaded_swaps(B, m, p, q - 1, i) else: return _select_with_cascaded_swaps(B, m, q + 1, r, i - k)
def _partition_around_median(A, w, p, r): n = r - p + 1 median = select(Array(A.elements), p, r, (n + 1) // 2) # we pass a copy of A because it will be modified in select q = p while A[q] != median: q += 1 A[q], A[r] = A[r], A[q] w[q], w[r] = w[r], w[q] i = p - 1 for j in between(p, r - 1): if A[j] <= median: i = i + 1 A[i], A[j] = A[j], A[i] w[i], w[j] = w[j], w[i] A[i + 1], A[r] = A[r], A[i + 1] w[i + 1], w[r] = w[r], w[i + 1] return i + 1
def _get_median_blackbox(A, p, r): n = r - p + 1 return select(A, p, r, (n + 1) // 2)