雙路快排
阿新 • • 發佈:2018-12-26
序列元素重複,是序列已經排好序的一種特殊情況,如果一個序列中的元素全部相同,也將出現最差情況。
如果序列中存在大量重複元素,在普通快排中,相等的元素會被全部放到分割槽點的一邊,這樣會大大增加快排的時間複雜度,雙路快排就是用來解決這個問題的。
能夠將序列均衡分開的分割槽點才是好的分割槽點。均勻分開意味著保持O(logn)的複雜度。
from random import shuffle, randrange def quick_sort(lst, left, right): # 當只有一個元素的時候退出遞迴 if left < right: p = partition(lst, left, right) # 左右分割槽分別遞迴 quick_sort(lst, left, p) quick_sort(lst, p+1, right) def partition(lst, left, right): rand = randrange(left, right) lst[left], lst[rand] = lst[rand], lst[left] # 隨機挑選出一個元素,與第一個元素交換,作為分割槽點 pivot = lst[left] # 以第一個元素為分割槽點 leftpos = left + 1 rightpos = right - 1 while leftpos <= rightpos: while leftpos <= rightpos and lst[leftpos] <= pivot: leftpos += 1 while leftpos <= rightpos and lst[rightpos] >= pivot: rightpos -= 1 if leftpos > rightpos: break lst[leftpos], lst[rightpos] = lst[rightpos], lst[leftpos] # 將pivot放入分割槽點 lst[leftpos-1], lst[left] = lst[left], lst[leftpos-1] # 返回分割槽點索引 return leftpos-1 source = list(range(10)) shuffle(source) print(source) quick_sort(source, 0, len(source)) print(source) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]