3.8 KiB
Conclusions on Sorting Algorithm
知识脉络总结
快速排序的思想是简单而深刻的,即分而治之的策略,需要注意它和归并排序在思想上的异同。快速排序的关键在于partition算法,本章给出了partition算法的三种实现,需要领会这三种不同的实现各自的特点是什么,是为了解决什么问题而出现的。需要指出的是,尽管在一般情况下快速排序运行的平均时间最短(这也是它被称作快速排序的原因),可是在最坏情况下快速排序仍然需要O(n^2)的时间,可以通过改造轴点的选择算法,在一定程度上减小最坏情况出现的概率。在平均情况下,快速排序仅需要O(nlogn)的时间复杂度,要会证明这个结论。
希尔排序的正确性和有穷性不言而喻,其时间复杂度主要取决于增量序列的选择,例如希尔序列就是一个比较糟糕的序列,需要能够领会为什么希尔序列的性能较差。为了分析希尔排序的时间复杂度,首先需要理解邮资问题和g-有序的序列经过h-排序后仍然保持g-有序的证明,在此基础上,即可针对不同的增量序列给出复杂度的证明。
本章的剩余部分主要讨论算法层面的问题,集中讨论了k选取问题,中位数选取问题,众数选取问题以及归并向量的中位数定位问题。
对于k选取问题,可以基于堆结构给出若干算法,这些算法在k很大或者很小时都具有较为优化的性能(O(n)),但是在k = O(n)时,算法的时间复杂度将退化为O(nlogn)。基于快速排序的思想,可以构造出快速选择(quickSelect)算法,它的平均时间复杂度为O(n),证明方法和快速排序相仿,然而在最坏情况下,它的时间复杂度可以达到O(n^2)。最后教材上给出了一个最坏情况下仍然可以保持O(n)的k选取算法,它的基本思想是将整个序列划分成三个子序列,并且使得其中小于轴点的子序列(记作L)以及大于轴点的子序列(记作G)的规模都不小于n / 4,从而一次迭代后问题的规模至少可以缩减为原来的3 / 4;为此,需要合理选择轴点,具体的做法是首先将整个序列平均划分为若干很小的子序列,每个子序列的规模为Q,并且求出这些子序列的中位数,再递归地计算这些中位数组成的中位数序列的中位数,将结果作为轴点。中位数选取问题是k选取问题的一个特例,这里不再赘述。
对于众数的选取问题,关键在于明确众数的定义乃是序列中出现频数多于一半的元素,从而可以证明教材所给算法的正确性。
关于归并向量的中位数选择,首先可以采用蛮力策略,假想地对两个有序向量进行归并,该策略的时间复杂度为O((m + n) / 2);若两个向量等长,则可以分别取两个向量的中位数以及逆向中位数进行比较,从而将问题的规模缩小一半;若允许向量不等长,可以对问题进行分类讨论:
- 若两个向量的规模差距巨大,则可以对更长的向量进行'裁剪',截除等长的两翼,从而问题归入到下一种情况。
- 两个向量规模相当,则以较短的向量的中位数
mid1为基础,分别构造出较长向量的前后两个中间数mid2a, mid2b,它们分别满足到向量的首尾的长度是mid1,通过将两者与mid1进行比较,从而可以截除接近一半的数据,问题的规模从而减少大约一半。这里不直接选择较长向量的中位数进行比较的原因,乃是需要保证两端截除的长度要相等,只有这样新问题的中位数才和原先的问题的中位数一致。