目录
前言
主要三部分:
思路
难点
具体代码(含有关键部分的注释)
一、快速排序的思路
- 将传入的alist 中的第一个数据作为首先排序的数据(mid_value)
- 建立两个游标(low and high),右游标左移开始,之后交换数据,左游标右移,直到两个游标相遇,结束循环,找到 mid_value的位置,此时alist 可以分为两部分,左边部分的元素值<mid_value; 右边部分的元素值>mid_value
- 新产生的两部分会重新利用快速排序算法进行排序(即利用递归的思想)
二、快速排序的难点
1. low游标和high 游标位置重合时候,停止循环,找打了mid_value的位置
- low 遍历 和high 遍历需要放在循环条件内部(#2 ; #1),不能放在外部,否则,二者会发生重合后错过
- 一旦两个重合,跳出#3的循环,则alist[low] or alist[high]=mid_value
2.遍历对象还是原来的alist,不能是新的对象
- 通过第一个值,可以将alist分为两部分,每部分需要再次排序算法进行新的排序,即可以利用递归思想
- 但是如果利用切片传入对象,则排序会产生新的对象,而不是在原来的alist上进行排序
例如:#5 和#6
Quick_sort(alist[0,low-1]),因为该切片产生的是一个新的迭代对象,不是在同一个列表上进行操作
3.传入还是整个列表alist,但是指定操作位置(first,last) #5,#6, 该数值主要取决于实例化对象后传入的数据
三、快速排序的代码展示
def Quick_sort(alist,first,last):
mid_value=alist[first]
"""产生low游标"""
low=first
"""产生high游标"""
high=last
"""找到mid_value的值的条件是low==high,否则high继续左移,low继续右移"""
"""一旦low==high,这个时候high or low 的位置是mid_value 的位置"""
if first>=last:
return
else:
while low <high:#3
"""右游标开始进行比较"""
while low <high and alist[high]>=mid_value:#1
high-=1 # 只有右边的数据>= mid_value时,才会进行游标移动(包含等于,因为可以将=mid_value的数值同一放在一边)
"""一旦high所指的元素小于mid_value时,就会退出#1的循环"""
alist[low]=alist[high]
while low<high and alist[low]<mid_value:#2
low+=1# 只有左边的数据>mid_value时候,low游标才会进行移动。
"""此时即使上一个循环#1已经将high游标所指的值进行交换,但是实际上,也满足该条件,以为交换就是交换的值<mid_value"""
alist[high]=alist[low]
"""#1和#2循环进行交替遍历,只有当low=high时候才会停止#1和#2的循环,即跳出#3的循环"""
alist[low]=mid_value #4
"""由mid_value产生的两部分需要进一步进行快速排序"""
"""first:指定low的起始位置"""
"""last:指定high 的起始位置"""
Quick_sort(alist,first,low-1)#5 :前面一部分,不能写成Quick_sort(alist[0,low-1]),因为该切片产生的是一个新的迭代对象,不是在同一个列表上进行操作
Quick_sort(alist, low+1, last)#6 :后面一部分,不能写成Quick_sort(alist[low+1,len(alist)-1]),因为该切片产生的是一个新的迭代对象,不是在同一个列表上进行操作
if __name__=="__main__":
li = [54,26,93,17,77,31,44,55,20]
print(li)
Quick_sort(li,0,len(li)-1)
print(li)