快速排序Qsort
快速排序Qsort是所有学习算法和数据结构最基础的一个部分,也是考试题和面试的一个小重点。
快速排序的时间复杂度为O(N*lgN),而且常数因子很小。
对于随机数据,效率特别高;
对于构造的恶意数据,最坏复杂度为O(N2),解决方案为采用随机化的快排。
除了时间效率上的优势,快速排序进行就地排序,即在原数组中进行元素交换,仅需要少量临时变量。这也是Qsort在空间上的优势。
注意:快速排序属于不稳定排序。
Qsort本质上是一种分治策略。每次通过数组内的元素交换,使得对于一个选定的元素X摆在合理的位置,即所有X左边的元素都不大于X,X右边的元素都不小于X。这样只需要分别对X左边和右边两个区间分别递归执行相同的过程即可完成整个序列的排序。
对于区间a[l,…,r],我们每次选定a[r]为上述的X。
然后从a[l]开始处理,直到处理到a[r-1]这个元素。处理过程中,把序列维护如下所示的情形:
如图,在逐个元素处理过程中,绿色表示不大于X的这些元素;黄色表示不小于X的这些元素;Y箭头处表示当前正在处理的元素Y;白色的部分表示还未处理的这些元素。
整个过程需要记录的一个最重要的位置是第一个黄色元素的位置,因为后续的交换都是围绕第一个黄色元素位置进行的(当然这个位置不是固定的,会随着元素的增多向后移动)。
比较Y和X,如果Y<=X,那么说明Y可以加入绿色阵营,此时只需要交换Y和第一个黄色位置的值,黄色的区域向右移动一位就可以持续保持当前的性质了;如果Y>X(等于号在哪个判断条件并不重要,为什么?),直接Y加入黄色阵营,啥也不要做,因为性质得到保持。
最后我们得到一个这样的结果,即除了最后一个a[r]没有处理。
此时我们只需要交换a[r]与第一个黄色的值,就可以了。
此时只要对左边和右边分别进行递归分治,就可以完成整个序列的排序了。
实现中还有一些细节请一定注意哦。