1.概念引入
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。 [2]
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
2 编写代码
def QuickSort(arr):
if len(arr)<2:#函数结束标志
return
mid=arr[0]#假设分界值为第0个元素
start=1
end=len(arr)-1
while start<end:
while arr[start]<mid and start<end:
start+=1#搜素比分界值大的元素索引
while arr[end]>mid and end>0:
end-=1#搜索比分界值小的元素索引
if start<end:
arr[start],arr[end]=arr[end],arr[start]#交换
arr[0],arr[end]=arr[end],arr[0]#将分界值放在序列的相应位置
QuickSort(arr[0:end])
QuickSort(arr[end+1:len(arr)])
arr=[5,2,33,23,14,12]
QuickSort(arr)
print(arr)
结果如下,可以发现序列中只有2和5的位置发生了变换而其他元素没有发生改变,经分析代码可知QuickSort(arr[0:end])和QuickSort(arr[end+1:len(arr)])这两
句代码没有得到相应的结果,而从逻辑上分析这样的代码并没有错。
后来我经过自己实验发现了相应的问题,原来是列表切片的问题,先观察如下代码
arr=[5,2,33,23,14,12]
arr0=arr[0:3]
arr0[1]=12
print(arr)
这里代码结果如下
发现没,虽然我们改变了切片中的值,但是在原始的序列中的值并没有发生改变
我们可以从这里得知切片只是相应的序列的一个副本,改变切片的值并不会影响原始序列。
所以将代码改为如下之后便可以
def QuickSort(arr,low,high):
if high-low<2:
return
mid=arr[low]
i=low+1
j=high
while i<j:
while arr[i]<mid and i<high:
i+=1
while arr[j]>mid and j>low:
j-=1
if i<j:
arr[i],arr[j]=arr[j],arr[i]
arr[low],arr[j]=arr[j],arr[low]
QuickSort(arr,0,j)
QuickSort(arr,j+1,high)
arr=[5,2,33,23,14,12]
QuickSort(arr,0,5)
print(arr)
最后附上官方的python代码
def quick_sort(data):
"""快速排序"""
if len(data) >= 2: # 递归入口及出口
mid = data[len(data)//2] # 选取基准值,也可以选取第一个或最后一个元素
left, right = [], [] # 定义基准值左右两侧的列表
data.remove(mid) # 从原始数组中移除基准值
for num in data:
if num >= mid:
right.append(num)
else:
left.append(num)
return quick_sort(left) + [mid] + quick_sort(right)
else:
return data
以上若有不恰当之处,敬请指出