序列元素重复,是序列已经排好序的一种特殊状况,若是一个序列中的元素所有相同,也将出现最差状况。
若是序列中存在大量重复元素,在普通快排中,相等的元素会被所有放到分区点的一边,这样会大大增长快排的时间复杂度,双路快排就是用来解决这个问题的。
可以将序列均衡分开的分区点才是好的分区点。均匀分开意味着保持O(logn)的复杂度。dom
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]