来自b站视频
算法原理
通过一次排序将要排序的数据分割为独立的两部分,其中一部分的所有数据都比另外一部分的所有数据要小,然后再按此方法对这两部分数据分别再进行快速排序,整个排序过程可以递归进行。
步骤
- 选择序列第一个数为基准mid_value,并给定所要排序的列表的起始位置first(low)和终止位置last(high)。
- high游标左移,当指向的数要小于mid_value时,停止左移,并将high游标指向的数据赋给low。
- low游标右移,当指向的数要大于mid_value时,停止右移,并将low游标指向的数据赋给high。
- 循环以上步骤,直到low==high时,退出循环。此时将mid_value赋给alist(low)(或high),即表示已找到mid_value值应处的位置。此时原列表被mid_value分割成左右两部分。
- 对左右两部分重复以上步骤,知道全部排序完毕。
如图所示
具体实现
def quicksort(alist, first, last):
'''快速排序'''
if first >= last:
return
low = first
high = last
mid_value = alist[first]
while low < high:
# high左移
while low < high and alist[high] >= mid_value:
high -= 1
alist[low] = alist[high]
#low右移
while low < high and alist[low] <= mid_value:
low += 1
alist[high] = alist[low]
# 从循环退出时,low==high
alist[low] = mid_value
# 对low左边的列表进行快速排序,
quicksort(alist, first, low-1) # 因为我们需要对alist列表本身进行排序,而不是一个新的列表进行排序,因此还传入alist,但是限定排序范围
# 对low右边的列表进行快速排序
quicksort(alist, low+1, last)
测试
if __name__ == '__main__':
li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
print('原序列:', li)
quicksort(li, 0, len(li)-1)
print('排序后:', li)
结果
原序列: [54, 26, 93, 17, 77, 31, 44, 55, 20]
排序后: [17, 20, 26, 31, 44, 54, 55, 77, 93]
时间复杂度
最优时间复杂度:O(nlogn)
(每一次所要排序的数字都在中间位置)
最坏时间复杂度:O(n^2)
稳定性:不稳定