def testPartition(): """Test partition function""" print "Test" arr = [4, 3, 2, 1] partition(arr, 0, len(arr) - 1) pivoted = [1, 3, 2, 4] assert isEqual(arr, pivoted)
def note(self): ''' Summary ==== Print chapter7.1 note Example ==== >>> Chapter7_1().note() ''' print('chapter7.1 note as follow') print('第7章 快速排序') print('快速排序是一种排序算法,对包含n个数的输入数组进行排序,最坏情况的运行时间为Θ(n^2)') print('虽然这个最坏情况运行时间比较差,但是快速排序通常是用于排序最佳的实用选择,这是因为其平均性能相当好') print('快速排序期望的运行时间为Θ(nlgn),且Θ(nlgn)记号中隐含的常数因子很小') print('快速排序能够进行就地排序,在虚存坏境中也能很好地工作') print('7.1 快速排序的描述') print('像合并排序一样,快速排序也是基于分治模式的') print(' 1.分解:数组A[p..r]被划分成两个(可能为空的)子数组A[p..q-1]和A[q+1..r]') print(' 使得A[p..q-1]中的每个元素都小于等于A(q),而且,小于等于A[q+1..r]') print(' 下标q也在这个划分过程中进行计算') print(' 2.解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]排序') print(' 3.合并:因为这两个子数组是就地排序的(不开辟新的数组),将他们合并不需要任何操作,整个数组A[p..r]已经排好序') print('子数组快速排序伪代码') print('QUICKSORT(A,p,r)') print(' 1. if q < r') print(' 2. q <- PARTITION(A,p,r)') print(' 3. QUICKSORT(A,p,q-1)') print(' 3. QUICKSORT(A,q+1,r)') print('排序完整的数组A,调用QUICKSORT(A,0,len(A))即可') print('快速排序算法的关键是PARTITION过程,它对子数组A[q..r]进行就地重排') print('PARTITION(A,p,r)') print(' 1. x <- A[r]') print(' 2. i <- p-1') print(' 3. for j <- p to r-1') print(' 4. if A[j] <= x') print(' 5. i <- i+1') print(' 6. exchange A[i] <-> A[j]') print(' 7. exchange A[i+1] <-> A[r]') print(' 8. return i + 1') A = [8, 9, 6, 7, 4, 5, 2, 3, 1] print('数组A', _deepcopy(A), '的快速排序过程为:', quicksort.quicksort(A)) A = [13, 19, 9, 5, 12, 8, 7, 4, 11, 2, 6, 21] print('练习7.1-1 数组A', _deepcopy(A), '的一步partition过程得到middle索引为:', quicksort.partition(A, 0, len(A) - 1)) A = [11, 11, 11, 11, 11] print('练习7.1-2 数组A', _deepcopy(A), '的一步partition过程得到middle索引为:', quicksort.partition(A, 0, len(A) - 1)) print('练习7.1-3 就一个长度为n的for循环,且一定会执行,所以时间复杂度为Θ(n),然后用确界的夹逼定义证明') print('练习7.1-4 不等号方向改变即可')
def quickselect(arr, low, high, k): if low < high: p = partition(arr, low, high) if p < k: quickselect(arr, p + 1, high, k) elif p > k: quickselect(arr, low, p - 1, k)
def randomized_selection(A, i, first=None, last=None): '''Returns the `i`th smallest element (indexed from 0) in `A[first:last]`. Requires `len(A) > i`. `A` must not contain duplicate elements. Recursively partitions `A`, as in randomized quicksort, where the pivot is chosen uniformly at random. >>> randomized_selection([3, 5, 7, 1, 9, 4, 6, 8], 4) 6 ''' first = first if first is not None else 0 last = last if last is not None else len(A) if last - first == 1: return A[first] pivot_index, _ = quicksort.partition(A, first, last, quicksort.random_pivot) normalized_pivot_index = pivot_index - first if normalized_pivot_index == i: return A[pivot_index] elif normalized_pivot_index > i: return randomized_selection(A, i, first, pivot_index) else: return randomized_selection(A, i - normalized_pivot_index - 1, pivot_index + 1, last)
def test_partition(): """Test the partition returns a modified list and value we expect.""" from quicksort import partition test_list = [0, 1] lo = 0 hi = len(test_list) - 1 pivot_point, a_list = partition(test_list, lo, hi) assert pivot_point == 1 assert a_list == [0, 1]
def selection(L, p, r, i): if p == r: return L[p] q = partition(L, p, r) k = q - p + 1 if i == k: return L[q] elif i < k: return selection(L, p, q - 1, i) else: return selection(L, q + 1, r, i - k)
def tail_recursive_quicksort(A, p, r): while p < r: q = partition(A, p, r) l_size = q - p r_size = r - q if l_size < r_size: tail_recursive_quicksort(A, p, q - 1) p = q + 1 # larger is from A[q+1...r], hence p = q+1 else: tail_recursive_quicksort(A, q + 1, r) r = q - 1 # larger is from A[p...q-1], hence r = q-1
def test_partition(seq: list, l_i: int, r_i: int, p_i: int, p_i_expected: int) -> None: """Verify partition step works.""" pivot = seq[p_i] seq_actual, p_i_actual = quicksort.partition(seq, l_i, r_i, p_i) assert p_i_actual == p_i_expected assert seq_actual[p_i_expected] == pivot assert all(x < seq_actual[p_i_expected] for x in seq_actual[:p_i_expected]) assert all(x > seq_actual[p_i_expected] for x in seq_actual[p_i_expected + 1:])
def order_select(l, p, r, i): # no randomization implemented here if p == r: return l[p] index = i - 1 pivot_index = partition(l, p, r) if index == pivot_index: return l[pivot_index] if index > pivot_index: return order_select(l, pivot_index + 1, r, index - pivot_index) else: return order_select(l, p, pivot_index - 1, i)
def introSort(data, start, end, depth): if start < end: if depth == 0: # Switch from quicksort to heapsort heapSort(data, start, end) Plot(max(data[start:end + 1]), data) return # Return the pivot index p = partition(data, start, end) # Sort all the elements to the left and to the right of the pivot introSort(data, start, p - 1, depth - 1) introSort(data, p + 1, end, depth - 1)
def kthtop(array,k): shuffle(array) low = 0 high = len(array) - 1 while(high > low): j = partition(array, low, high) if j < k: low = j + 1 elif j > k: high = j - 1 else: return array[k] return array[k]
def RSelection(A, low, n, order_statistic): if low == n: return A[low] if order_statistic == 0: return -1 if n > low: pivot = random.randrange(low, n + 1) pivot_index = quicksort.partition(A, 0, n, pivot) i = pivot_index - low + 1 if i == order_statistic: return A[pivot_index] elif i > order_statistic: return RSelection(A, low, pivot_index - 1, order_statistic) else: return RSelection(A, pivot_index + 1, n, order_statistic - i)
def RSelect(arr, l, r, k): if len(arr) == 1: return arr[0] if l > r: i = l else: i = randint(l, r) print(f"i : {i}") arr[l], arr[i] = arr[i], arr[l] j = partition(arr, l, r) if j + 1 == k: print(arr) return arr[j] elif j > k: return RSelect(arr, l, j - 1, k) else: return RSelect(arr, j + 1, r, k)
def select_statistic_random(lst, start, end, i): """ select i-statistic algorithm use random element everytime """ if start >= end: return lst[start] # select random pivot element pivot = random.randint(start, end) # swap pivot and last element into list lst[-1], lst[pivot] = lst[-1], lst[pivot] # regrouping the list new_pivot = partition(lst, start, end) k = new_pivot - start + 1 if i == k: return lst[new_pivot] elif i < k: # run recursive quick sort for left half return select_statistic_random(lst, start, new_pivot - 1, i) else: # run for right half return select_statistic_random(lst, new_pivot + 1, end, i - k)
def top(i, array, start=None, end=None): try: if i > len(array): raise UnboundLocalError('Error: ith position greater that the length of the array') quicksort.randomize_pivot(array, end, start) pivot = quicksort.partition(array, start, end) ith_pos = i-1 if ith_pos == pivot: return array[pivot] if ith_pos < pivot: return top(i, array, 0, pivot-1) else: return top(i, array, pivot + 1, end) except UnboundLocalError as e: raise e
def select(data, p, r, i): """ Selects the ith smallest elements of self.data from p to r. Guarantees a good split by choosing the median of medians of blocks of size 5. Attributes: p -- a starting index r -- an end index i -- an index of the smallest element """ if p == r: return data[p] # divide the group of elements into n/5 groups of 5 elements each medians = [] # a list of medians from each group last = r j = p while j < last + 1: end = j + 5 if end > last + 1: end = last + 1 insertion_sort(data, j, end) mid = (j + end - 1) / 2 medians.append(data.pop(mid)) last -= 1 j += 4 # put medians at the head of the list data[p:p] = medians # use select recursively to find the median of medians median = select(data, p, p + len(medians) - 1, (len(medians) + 1) / 2) data[data.index(median)], data[r] = data[r], data[data.index(median)] q = quicksort.partition(data, p, r) k = q - p + 1 if i == k: return data[q] elif i < k: return select(data, p, q - 1, i) else: return select(data, q + 1, r, i - k)
def solution(A): m = 1 left = 0 right = len(A) - 1 s = [(0, 0)] while left < right: i, j = partition(A, left, right) _jl = j - left _ri = right - i if _jl < m and _ri < m: left, right = s.pop() elif _jl < m and _ri >= m: left = i elif _jl >= m and _ri < m: right = j elif _jl >= m and _ri >= m: if _jl >= _ri: s.append((left, j)) left = i else: s.append((i, right)) right = j return A
def test_kind_of_unsorted_list_4(self): array = [1, 3, 2, 4] pivot = partition(array, 2) self.assertEqual(pivot, 1) self.assertPivot(array, pivot)
def test_sorted_non_contiguous_list(self): array = [1, 2, 4] pivot = partition(array, 2) self.assertEqual(pivot, 2) self.assertPivot(array, pivot)
def test_unsorted_list(self): array = [3, 1, 2] pivot = partition(array, 2) self.assertEqual(pivot, 1) self.assertPivot(array, pivot)
def test_reversed_list(self): array = [3, 2, 1] pivot = partition(array, 1) self.assertEqual(pivot, 1) self.assertPivot(array, pivot)
def randomizedpartition(A, p, r): i = random.randrange(p, r) quicksort.exchange(A, i, r) return quicksort.partition(A, p, r)
def test_rotated_list__5(self): array = [4, 1, 5, 2, 3] pivot = partition(array, 3) self.assertEqual(pivot, 1) self.assertPivot(array, pivot)
def randomized_partition(A, p, r): i = random.randint(p, r) A[i], A[r] = A[r], A[i] return partition(A, p, r)
def test_partition(self): a = [2, 1, 3] q = qs.partition(a, 0, len(a) - 1) self.assertEqual(q, 2)
def random_partition(arr, left, right): p = random.randint(left, right) arr[right], arr[p] = arr[p], arr[right] mid = partition(arr, left, right) return mid
def partition_random(A, p, r): i = random.randint(p, r) A[r], A[i] = A[i], A[r] return quicksort.partition(A, p, r)
def test_partition_2(self): array = [3, 8, 2, 5, 1, 4, 7, 6] self.assertEquals(partition(array, 0, 7), (0, 4, 6, 7))
def test_yet_another_unsorted_list_4(self): array = [3, 1, 2, 4] pivot = partition(array, 2) self.assertEqual(pivot, 1) self.assertPivot(array, pivot)
def test_partition(): # l&i r arr = [4, 8, 7, 0, 2, 6, 5, 3, 1] i = 0 # index of pivot element l = 0 # index of starting element r = len(arr) - 1 # index of ending element assert i == 0, 'index of pivot element is set to first element' assert arr[i] == 4 i = partition(arr, l, r, i) assert i == 4 assert arr[i] == 4 assert all(x < 4 for x in arr[l:i]) assert all(x > 4 for x in arr[i+1:r]) # l i r arr = [4, 8, 7, 0, 2, 6, 5, 3, 1] i = 1 # index of pivot element l = 0 # index of starting element r = len(arr) - 1 # index of ending element assert i == 1 assert arr[i] == 8 i = partition(arr, l, r, i) assert i == 8 assert arr[i] == 8 assert all(x < 8 for x in arr[l:i]) assert all(x > 8 for x in arr[i+1:r]) # l i&r arr = [4, 8, 7, 0, 2, 6, 5, 3, 1] i = 8 # index of pivot element l = 0 # index of starting element r = len(arr) - 1 # index of ending element assert i == 8 assert arr[i] == 1 i = partition(arr, l, r, i) assert i == 1 assert arr[i] == 1 assert all(x < 1 for x in arr[l:i]) assert all(x > 1 for x in arr[i+1:r]) # l i r arr = [4, 8, 7, 0, 2, 6, 5, 3, 1] # [ 7, 0, 2, 6, 5 ] # [ 0, 2, 7, 6, 5 ] # 0 1 2 3 i = 4 # index of pivot element l = 2 # index of starting element r = 6 # index of ending element assert i == 4 assert arr[i] == 2 i = partition(arr, l, r, i) assert i == 3 assert arr[i] == 2 assert all(x < 2 for x in arr[l:i]) assert all(x > 2 for x in arr[i+1:r]) # l&i&r arr = [1] i = 0 # index of pivot element l = 0 # index of starting element r = 0 # index of ending element comparisons = Counter() assert i == 0 assert arr[i] == 1 i = partition(arr, l, r, i, count=comparisons) assert i == 0 assert arr[i] == 1 assert comparisons.total == 0 assert all(x < 1 for x in arr[l:i]) assert all(x > 1 for x in arr[i+1:r]) # l i&r arr = [1, 2] i = 1 # index of pivot element l = 0 # index of starting element r = 1 # index of ending element comparisons = Counter() assert i == 1 assert arr[i] == 2 i = partition(arr, l, r, i, count=comparisons) assert i == 1 assert arr[i] == 2 assert comparisons.total == 1 assert all(x < 2 for x in arr[l:i]) assert all(x > 2 for x in arr[i+1:r]) # l&i r arr = [1, 2] i = 0 # index of pivot element l = 0 # index of starting element r = 1 # index of ending element comparisons = Counter() assert i == 0 assert arr[i] == 1 i = partition(arr, l, r, i, count=comparisons) assert i == 0 assert arr[i] == 1 assert comparisons.total == 1 assert all(x < 1 for x in arr[l:i]) assert all(x > 1 for x in arr[i+1:r])
def test_sorted_list(self): array = [1, 2, 3] pivot = partition(array, 1) self.assertEqual(pivot, 1) self.assertPivot(array, pivot)
def test_quicksort(): eq_(quicksort.partition([4, 5, 3, 7, 2]), [3, 2, 4, 5, 7])
def test_partition_1(self): array = [3, 5, 1, 4, 2, 6] self.assertEquals(partition(array, 0, 5), (0, 4, 6, 5))
def test_partition(self): a = [2, 8, 7, 1, 3, 5, 6, 4] partition(a, 0, 7) self.assertEquals(a, [2, 1, 3, 4, 7, 5, 6, 8])
def randomquicksort(A: list, begin: int, end: int): if end > begin: randomize(A, begin, end) compare = quicksort.partition(A, begin, end) randomquicksort(A, begin, compare - 1) randomquicksort(A, compare + 1, end)
def randomised_partition(A, p, r): random_index = random.randint(p, r) A[r], A[random_index] = A[random_index], A[r] return partition(A, p, r)