常见的排序算法有以下几种:
- 递归性排序
- 归并排序:归并排序的主要思想是分治,也就是先把数组分成两部分,当两部分都有序时,然后再将两部分进行二路归并。需要注意的是归并排序的时间复杂度分析方法,就是画出$T(n) = 2T(n/2) + cn$ 的递归树,并计算最终时间复杂度。但是要注意的是,归并排序在进行二路归并时,可能会产生额外的空间复杂度。
- :快速排序的思路也是分治,但分治之前需要选择一个主元作为基准,将主元放在应该在的位置,并且数组左边比主元小,右边比主元大。这样如果当左边有序和右边有序时,整个数组就有序了。假设主元位置为i,快速排序复杂度为$T(n) = T(i) + T(n - i - 1) + cn$ 。由于i的不确定性导致快速排序的最坏情况下时间复杂度为$T(n) = T(n-1) + T(0) + cn = O(n^2)$ ,而平均情况下是$T(n) = 2T(\frac{n-1}{2}) +cn = nlogn$。 快速排序不需要额外的空间。
- 非递归型排序
- 非比较排序:非比较排序的时间复杂度可以达到$O(n)$ 。
- 计数排序、基数排序、桶排序
- 计数排序:已知最大值K。利用数组
int[K]
统计每个数字的小于等于它的个数,将这个个数作为这个数字的idx - 基数排序:分别对数字的个位、十位、…、d位依次进行计数排序
- 桶排序:将数字分别放入桶里。
- 计数排序:已知最大值K。利用数组
- 计数排序、基数排序、桶排序
因此我们做出如下总结:
排序方法 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 其它要点 |
---|---|---|---|---|
归并 | $O(nlogn)$ | $O(nlogn)$ | $O(n)$ | 递归树 |
快排 | $O(nlogn)$ | $O(n^2)$ | $O(1)$ | 快速选择【九章算法强化班】两指针 快排优化算法:随机选择pivot |
插入、 选择、 冒泡、 希尔 |
$O(n^2)$ | $O(n^2)$ | $O(1)$ | |
计数排序 | $O(n)$ | $O(n)$ | $O(K)$ | 已知数组最大值K |
基数排序 | $O(d(n+10))$ | $O(d(n+10))$ | $O(10)$ | |
桶排序 | $O(n)$ | $O(n)$ | 大数排序 |