Files
912-notes/thu_dsa/chp12/sort.md
2019-11-17 19:55:30 +08:00

20 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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`进行比较,从而可以截除接近一半的数据,问题的规模从而减少大约一半。这里不直接选择较长向量的中位数进行比较的原因,乃是需要保证两端截除的长度要相等,只有这样新问题的中位数才和原先的问题的中位数一致。