快速排序采用分治法策略来把一个序列分成两个子序列。
步骤
- 从数列中挑选出一个元素,称为基准;
- 重新排序数列,所有元素比基准小的放在基准前面,所有元素比基准大的放在基准后面(相同的数据可以放在任意一边),在这个分区结束后,该基准处于数列的中间位置,这个称为分区操作;
- 递归的把小于基准值的子数列和大于基准值的子数列排序
python代码
def quick_sort(alist, start, end):
if start >= end;
return
privot = alist[start]
left = start
right = end
while left < right:
while left < right and alist[right] > privot:
right -= 1
alist[left] = alist[right]
while left < right and alist[left] <= privot:
left += 1
alist[right] = alist[left]
alist[low] = privot
quick_sort(alist, start, low-1)
quick_sort(alist, low+1, end)
个人理解如下:
def quick_sort_2(li, start, end):
# 递归出口
if start > end:
return li
mark = li[start] # 设置起始元素为要寻找位置的基准元素
low = start # low为序列左边的由左往右移动的游标
high = end # high为序列右边由右往左移动的游标
while low < high: # 外层循环决定游标移动的次数
# 如果右边游标指向的元素大于基准元素,则high游标往左继续移动一位
while low < high and li[high] >= mark:
high -= 1
# 如果low游标指向的元素小于基准元素,则low游标往右继续移动一位
while low < high and li[low] <= mark:
low += 1
# 退出while循环表示两边游标对应的元素交换位置
li[low], li[high] = li[high], li[low]
# 退出循环后,low和high重合,此时所指位置为基准元素的正确位置,交换两者位置。
li[start], li[high] = li[high], li[start]
# 对基准元素左边的子序列进行快速排序
quick_sort_2(li, start, low - 1)
# 对基准元素右边的子序列进行快速排序
quick_sort_2(li, low + 1, end)
return li
if __name__ == '__main__':
ql = [5, 4, 2, 6, 4, 3, 24, 5, 7, 3]
# quick_sort(ql, 0, len(ql) - 1)
print(quick_sort_2(ql, 0, len(ql) - 1))
为什么快速排序要从右边开始?
如下列表[6,1,2,7,9]
如果我们开始从左往右,那么low游标对应的数字为7,high游标对应的元素也为7,此时交换6和7的位置,那么7到了6的左边,6的左边对应的元素不是都小于6(包含7),故排序要从右往左开始。