之前两篇关于排序算法的综述以及平方阶复杂度的3种具体类型的排序算法,这一篇将具体介绍其中平均时间复杂度在平方阶 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)的三个排序算法,以及各种算法的代码实现(亲测正确)。
快速排序
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 O ( n l o g n ) O(nlogn) O(nlogn)次比较。在最坏状况下则需要 O ( n 2 ) O(n^2) O(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 O ( n l o g n ) O(nlogn) O(nlogn)算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
算法思想
过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在简单排序基础上的递归分治法。
算法步骤
- 从数列中挑出一个元素,称为 “基准”(pivotpos)。
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
图示
算法复杂度
- 最优情况
- Partition每次都划分得很均匀,如果排序n个关键字,其递归树的深度就为 [ l o g 2 n ] + 1 [log_2n]+1 [log2n]+1( [x] 表示不大于 x 的最大整数),即仅需递归 l o g 2 n log_2n log2n次。第一次Partiation应该是需要对整个数组扫描一遍,做n次比较。然后,获得的枢轴将数组一分为二,那么各自还需要T(n/2)的时间(注意是最好情况,所以平分两半)。故为