快排简介
快速排序(Quicksort)是对冒泡排序算法的一种改进。
快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快排算法原理
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
(1) 首先设定一个分界值(pivot):通过该分界值将数组分成左右两部分(partition)。
(2) Compare and Swap:将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
(3) Recursive:然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4) 重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
动图演示快排原理:
QuickSort Algorithm视频演示:
https://video.kuaishou.com/short-video/3xytg4s3xviab3u
算法原理详解
快速排序(QuickSort )是一个分治算法(Divide and Conquer)。它选择一个元素作为枢轴元素(pivot),并围绕选定的主元素对给定数组进行分区(partition)。快速排序有很多不同的版本,它们以不同的方式选择枢轴。
- 总是选择第一个元素作为 pivot。
- 总是选择最后一个元素作为 pivot。
- 随机选一个元素作为 pivot。
- 选择中值作为 pivot。
QuickSort 中的关键步骤是 partition()。在数组中选择的一个元素为支点(pivot), 把所有小于 pivot 的元素放到 pivot 左面, 大于 pivot 的放右边。这样数组 x[n] 会被划分成3个部分:
x[0] , ... , x[pivot - 1]
x[pivot]
x[pivot+1] , ... , x[n]
所有这应该是在线性时间内完成。
接下来,就是递归调用:
Pseudo Code for recursive QuickSort function
Partition Algorithm
There can be many ways to do partition, following pseudo code adopts the method given in CLRS book.
The logic is simple, we start from the leftmost element and keep track of index of smaller (or equal to) elements as i. While traversing, if we find a smaller element, we swap current element with arr[i]. Otherwise we ignore current element.
Pseudo code for partition()
Illustration of partition()
快排算法源代码
Java 源代码
Kotlin 源代码(优化版本)
参考资料
1、《代码之美》Chapter 3:我从未编写过的最漂亮的代码(Jon Bentley)
2、QuickSort:https://www.geeksforgeeks.org/quick-sort/
3、快速排序百科:https://baike.baidu.com/item/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/369842