快速排序是一种经典的排序算法。在面试中经常会被问到。这里咱们就分析一下这个快速排序法
首先它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边 此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值, 将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也做类似处理
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序 当左、右两个部分各数据排序完成后,整个数组的排序也就完成了
快排示意图
示例代码:
def quick_sort(alist, start, end):
"""快速排序"""
# 递归的结束条件
if start >= end:
return
# 界限值
mid = alist[start]
# 左右游标
left = start
right = end
while left < right:
# 从右边开始找寻小于mid的值 归类到左边
while alist[right] >= mid and left < right:
right -= 1
alist[left] = alist[right]
# 从左边开始找寻大于mid的值 归类到右边
while alist[left] < mid and left < right:
left += 1
alist[right] = alist[left]
# 循环一旦结束了 证明找到了mid应该在的位置
alist[left] = mid
# 递归操作
quick_sort(alist, start, left-1)
quick_sort(alist, right+1, end)
if __name__ == '__main__':
# alist = [4, 5, 5, 3, 3, 1, 6, 8, 7, 2]
alist = [5, 5, 1, 2]
quick_sort(alist, 0, len(alist)-1)
print(alist)
再下来我们该研究一下快排的时间复杂度了:
1) 层数代表排序的轮数 : n 每一轮比较n次 最差时间复杂度: O(n2)
2) n/2/2/2... = 1 --> 1*2*2*2*... = n --> 2的多少次方为n --> log2n 层数代表排序的轮数 : logn 每一轮比较n次 最优时间复杂度: O(nlogn)
最后再来探讨一下稳定性:快排是 不稳定算法