设定一个中间值,如下所示:
low从开始位置找low是找比54小的,26比54小合格 high是从末尾位置找比54大的,如下所示:
low和high重合后第一轮循环结束
第一轮递归后的结果如下所示:
还需要处理值相等的情况,如下所示:
比如有一个值是54(也可能是多个),正好跟中间值也就是基准值相等,解决思路就是54在一边出现(或者说在一边处理),不是左边出现就是右边出现,把等于这个情况放到一边去处理,不是在low这边就是在high这边。
上面的high继续左移的时候,high和low就重合了。
上面的起始位置是动态的,不是固定的0,low-1这样的
代码如下所示:
# coding=utf-8
def quick_sort(alist,first,last):
"""快速排序"""
if first >= last: #这两个相等表示有一个元素,则终止循环即可。
return
#n = len(alist)
#mid_value = alist[0]
# low = 0
# high = n - 1
mid_value = alist[first]
low = first
high = last
#high对应的值大于中间值的时候,high需要往左走,即high-=1,走到什么时候呢?即low和high没有相遇的时候,high的值需要一直走,所以外面又加了一层循环 while low<high:
#流程是交替进行的,先是high走,high走完了然后是low走,然后又是high走,即左移右移左移依次交替进行,所以外面还需要套一层交替进行的代码
while low<high:
#这个是high往左移动过程的代码
#中间值解决思路就是中间值54在一边出现(或者说在一边处理),不是左边出现就是右边出现。
#把等于这个情况放到一边去处理,不是在low这边就是在high这边,所以下面的alist[high] >= mid_value加了一个等号
while low < high and alist[high] >= mid_value:
high -= 1
#代码修改了一下,high往左移动,跳出while循环的时候,可以查看一下while循环的条件,可能是high往左走的过程中遇到了比中间值小或者等于中间值的情况,则需要把high的值赋予到low上面,low上面存的是比中间值小的数值
alist[low] = alist[high]
#low+=1 #因为low里面的值比中间值小,所以low需要加1,这样写有可能会错过low和high重合的情况,注释掉
# 这个是low往右边移动过程的代码
while low<high and alist[low]<mid_value:
low+=1
alist[high] = alist[low]
#high -= 1,这样写有可能会错过low和high重合的情况,注释掉
#从循环退出时,low == high
alist[low] = mid_value
#对low左边的列表执行快速排序
#这块low-1减的时候有可能比first小,所以停止执行的条件我们修改为first>=last
quick_sort(alist,first,low-1)
# 对low右边的列表执行快速排序
quick_sort(alist,low+1,last)
if __name__ == "__main__":
li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
print(li)
quick_sort(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]
"""