![676ebc4e6acd0eed37b6e215a697a555.png](https://i-blog.csdnimg.cn/blog_migrate/c7148808c976347ea26597f242077806.jpeg)
前言
之前介绍的插入排序与冒泡排序算法存在一个很明显的问题,就是基于比较和交换的排序策略,从根本上无法对平均时间复杂度进行优化,没有改进的余地和空间。
但是如果我们摒弃插入排序与冒泡排序的思想,另辟蹊径是否能够提升排序效果呢?
答案是肯定的。下面将介绍基于分治策略的两种排序算法,分别是快速排序算法和归并排序算法,并对其进行时间复杂度分析和改进。
一、分治策略
首先,我们先了解一下什么是分治策略。
分治策略:如果一个规模为n的问题,若该问题可以很容易地解决(n较小)时,则直接解决;否则将其分解为k个规模较小的子问题,这些子问题相互独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解进行合并得到原问题的解。
如果子问题不独立有公共子问题,那么我们则使用动态规划的思想求解该问题。
分治策略分成三个步骤:
- 分解:将原问题分解为若干个规模较小的子问题,相互独立,与原问题形式形同的子问题。
- 解决:若子问题规模较小而容易被解决则直接解决,否则递归地解决各个子问题。
- 合并:将各个子问题的解合并为原问题的解。
![3d2753ba0c4e9d1fd66404a8c407eb38.png](https://i-blog.csdnimg.cn/blog_migrate/2f7e695fff15ec97b68feccf78f9ca88.jpeg)
分治法时间复杂度如下
当采用分治法时,
分治与递归是一对“孪生兄弟”,经常搭配在一起使用,解决很多问题。
采用分治策略主要有两种算法:
- 快速排序:hard division, easy combination.
- 归并排序:easy division, hard combination.
二、快速排序过程
![78d04cf4933fa6ac4dd094edf95193d8.gif](https://i-blog.csdnimg.cn/blog_migrate/df23f700c8e84f6679ee935cfe9d3ccf.gif)
上图是一个快速排序算法的动态演示,略显抽象,我们可以通过另一幅图片来看。
![7f4ef371f4c68ee3b617616182e664bb.gif](https://i-blog.csdnimg.cn/blog_migrate/d2b829a84bde8a70fea1f94adfe28a09.gif)
上图的过程是快速排序的基本过程,快排会先选择一个元素作为枢轴,小的放在他的左边,大的放在他的右边,从而经过n-1次比较,将原问题划分为两个相同的子问题。进而再对两个子问题进行相同的求解过程。
示例代码如下:
public
三、快排时间复杂度分析
有了代码实现,下面我们要进行快排的时间复杂度分析。
还是按照我们的脉络,先分析最坏情况,再分析最好情况。
- 最坏情况时间复杂度
最坏情况是选取的枢轴是最小的元素,导致划分后的问题规模是0和n-1,然后接下来枢轴仍然是最小值。给出一个例子,”1, 2, 3, 4, 5, 6, 7, 8, 9, 10“,假设每次选取第一个元素作为枢轴,那么这个序列就对应着最坏情况。
我们递推求得该问题的最坏情况时间复杂度为
2. 平均时间复杂度
h设所有的可能的输入序列都是等可能性出现的。
![9dc97195d188cbf192657cf3617b2dd1.png](https://i-blog.csdnimg.cn/blog_migrate/11b616d304ad07f7ff0fcdcd2a819bb8.jpeg)
我们将所有可能的情况加和起来,进一步可以得到
可以通过将上式展开得到下式。
进而我们有两种方法来得到A(n),一种是估算法,一种是直接推理法。
①估算法
估算快排时间复杂度为
![1ceb7ffd667b4692e33a05117f580be7.png](https://i-blog.csdnimg.cn/blog_migrate/b3b1dfdcf25c829a629970ed26734bb6.jpeg)
根据定理3.7的第二个条件,进而我们可以得到
![f1722cb4e5a0f75e2e102ffea6bf8e41.png](https://i-blog.csdnimg.cn/blog_migrate/e262826e70edc1322e31e5b80acb34a1.jpeg)
![fe0520c966e56a6bc781a2e42f391afb.png](https://i-blog.csdnimg.cn/blog_migrate/876be78108cc5b6fc8fa114ab075485a.jpeg)
![65320a92ba012da222d7941a81399f29.png](https://i-blog.csdnimg.cn/blog_migrate/9a95a4ed8e6f91a2df0baad215c87080.png)
②直接推理计算
这里直接给出过程,大家可以按照过程推导一遍,此处并不做特殊要求。
![13ca3b8180fe97936c63631dd8ff37a9.png](https://i-blog.csdnimg.cn/blog_migrate/41e14182a973b3048c4082053ded95b8.jpeg)
![e9e59d9270e6204b8778cf2960655a99.png](https://i-blog.csdnimg.cn/blog_migrate/c2694e44198269f0af79906eb3867bf7.jpeg)
四、快速排序算法的改进
改进措施:
- 递归:因为递归调用过程是要消耗计算资源的,因此可以改为非递归
- 小排序问题:小排序可以使用其他排序算法
- 枢轴的选取--随机打乱、随机选择等等方法
但是随机打乱、随机选择还是无法避免最坏情况的出现。如果快排策略不改变,无论如何选用枢轴,都存在最坏情况