版权声明:如需转载,请注明原文出处,作者:vergilben https://blog.csdn.net/weixin_42751456/article/details/89004032
快速排序
快速排序简介:
- 从数列中挑出一个元素,称为基准点(pivot)。
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
假如下面的数是我们要排列的数:
我们假设25就是我们选定的基准点,现在把25放到一边去,让low开始右移:
此时,low的值29比25大,所以我们交换low和high的值,交换完成之后low的值就比基准点小,所以low继续右移:
low移动到12,比基准点小,继续右移至52:
此时low的值比基准点25大,而此时high的值也比基准点大,所以high开始左移,直至20处比基准点小:
这时,low和high交换值,low的值就比25小,low右移至37:
此时,low和high的值均大于基准点的值,所以high开始左移:
high又比基准点小,low和high交换值,low右移:
low的值又比基准点的值大,low和high交换位置,此时low和high的值都比基准点的值大,high左移,low和high重合:
这时,基准点的值就可以放到重合部分的左边了,且此时,基准点左边的值都比基准点小,基准点右边的值都比基准点大:
现在,以25为基准点,左边和右边分别为两个列表,分开来再进行如上过程:
我们用一张图再解释一下:
以上,就是快速排序的实现过程,那么我们怎么用代码来进行实现呢?我们用另一种思维方式来实现,从high的值开始:
# -*-coding:utf-8-*-
def QuickSort(lyst, start, end):
"""快速排序"""
# 递归的退出条件
if start >= end:
return
# 设定起始元素为要寻找位置的基准元素
mid = lyst[start]
# low为序列左边的由左向右移动的游标
low = start
# high为序列右边的由右向左移动的游标
high = end
while low < high:
# 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
while low < high and lyst[high] >= mid:
high -= 1
# 将high指向的元素放到low的位置上
lyst[low] = lyst[high]
# 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
while low < high and lyst[low] < mid:
low += 1
# 将low指向的元素放到high的位置上
lyst[high] = lyst[low]
# 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
# 将基准元素放到该位置
lyst[low] = mid
# 对基准元素左边的子序列进行快速排序
QuickSort(lyst, start, low-1)
# 对基准元素右边的子序列进行快速排序
QuickSort(lyst, low+1, end)
使用一下:
lyst = [54,26,93,17,77,31,44,55,20]
QuickSort(lyst,0,len(lyst)-1)
print(lyst)
结果:
[17, 20, 26, 31, 44, 54, 55, 77, 93]
如需转载,请注明原文出处,作者:vergilben