快速排序总体上有四个步骤:
- 选取一个项为基准点(pivot);
- 将列表中的项进行分区处理,把比基准点小的数字放到基准点的左侧,比基准点大的点放到基准点的右侧。所以此时,尽管其他项是乱的,但基准点的位置已经被确定,即基准点的位置已经排序完毕;
- 分而治之,将列表划分割为更小的列表,将基准点左右部分分别作为子列表重复进行第一步的操作,取一个点作为基准点进行排序;
- 每次遇到少于俩个项的子列表就结束这个过程;
根据以上四点发现快速排序这个过程可以由递归来实现。
代码如下:
import random
def quicksort(listp) :
quicksorthelper(listp, 0, len(listp)-1)
#列表索引从0开始
def partition(listp,left,right):
middle = (left + right) // 2
pivot = listp[middle]
listp[middle] = listp[right]
listp[right] = pivot#选取最中间的为基准点并将其调换到最后
boundary = left
for index in range(left , right):
if listp[index] < pivot:
swap(listp,index,boundary)
boundary+=1
swap(listp,boundary,right)
return boundary
def swap(listp, index, boundary):
temp = listp[index]
listp[index] = listp[boundary]
listp[boundary] = temp
def quicksorthelper(listp, left, right) :
if left < right:
pivotlocation=partition(listp, left, right)
quicksorthelper(listp, left, pivotlocation-1)#pivotlocationn处已经排序完毕
quicksorthelper(listp, pivotlocation+1, right)
a=[]
for i in range(50):
a.append(random.randint(0, 100))
print(a)
print('\n')
quicksort(a)
print(a)
这里的不足之处在于选取的基准点过于特殊,每次都是中间的那个,有较大可能使得算法时间复杂度为最高的,我们可以采取用random生成随机基准点。
另外quicksorthelp的作用是对快速排序算法进行一个封装,隐藏递归调用的额外参数。