
前言
之前介绍的插入排序与冒泡排序算法存在一个很明显的问题,就是基于比较和交换的排序策略,从根本上无法对平均时间复杂度进行优化,没有改进的余地和空间。
但是如果我们摒弃插入排序与冒泡排序的思想,另辟蹊径是否能够提升排序效果呢?
答案是肯定的。下面将介绍基于分治策略的两种排序算法,分别是快速排序算法和归并排序算法,并对其进行时间复杂度分析和改进。
一、分治策略
首先,我们先了解一下什么是分治策略。
分治策略:如果一个规模为n的问题,若该问题可以很容易地解决(n较小)时,则直接解决;否则将其分解为k个规模较小的子问题,这些子问题相互独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解进行合并得到原问题的解。
如果子问题不独立有公共子问题,那么我们则使用动态规划的思想求解该问题。
分治策略分成三个步骤:
- 分解:将原问题分解为若干个规模较小的子问题,相互独立,与原问题形式形同的子问题。
- 解决:若子问题规模较小而容易被解决则直接解决,否则递归地解决各个子问题。
- 合并:将各个子问题的解合并为原问题的解。

分治法时间复杂度如下
当采用分治法时,
分治与递归是一对“孪生兄弟”,经常搭配在一起使用,解决很多问题。
采用分治策略主要有两种算法:
- 快速排序:hard division, easy combination.
- 归并排序:easy division, hard combination.
二、快速排序过程

上图是一个快速排序算法的动态演示,略显抽象,我们可以通过另一幅图片来看。

上图的过程是快速排序的基本过程,快排会先选择一个元素作为枢轴,小的放在他的左边,大的放在他的右边,从而经过n-1次比较,将原问题划分为两个相同的子问题。进而再对两个子问题进行相同的求解过程。
示例代码如下:
public
三、快排时间复杂度分析
有了代码实现,下面我们要进行快排的时间复杂度分析。
还是按照我们的脉络,先分析最坏情况,再分析最好情况。
- 最坏情况时间复杂度
最坏情况是选取的枢轴是最小的元素,导致划分后的问题规模是0和n-1,然后接下来枢轴仍然是最小值。给出一个例子,”1, 2, 3, 4, 5, 6, 7, 8, 9, 10“,假设每次选取第一个元素作为枢轴,那么这个序列就对应着最坏情况。
我们递推求得该问题的最坏情况时间复杂度为
2. 平均时间复杂度
h设所有的可能的输入序列都是等可能性出现的。

我们将所有可能的情况加和起来,进一步可以得到
可以通过将上式展开得到下式。
进而我们有两种方法来得到A(n),一种是估算法,一种是直接推理法。
①估算法
估算快排时间复杂度为

根据定理3.7的第二个条件,进而我们可以得到



②直接推理计算
这里直接给出过程,大家可以按照过程推导一遍,此处并不做特殊要求。


四、快速排序算法的改进
改进措施:
- 递归:因为递归调用过程是要消耗计算资源的,因此可以改为非递归
- 小排序问题:小排序可以使用其他排序算法
- 枢轴的选取--随机打乱、随机选择等等方法
但是随机打乱、随机选择还是无法避免最坏情况的出现。如果快排策略不改变,无论如何选用枢轴,都存在最坏情况