一、引子
在面试的时候,很常见的是给你出一两道简单的算法题,让你去实现。或是直接说
“同学你对XX排序了解多少?”
当你叭叭叭回答完了之后,考官面带笑容,推过来一张纸
那你能实现一下吗?
所以今天打算把常考的排序算法总结一下,并且提供一两个模板,以供之后复习使用。
二、基本性质
排序算法 | 最好时间复杂度 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O ( N ) O(N) O(N) | O ( N 2 ) O(N^2) O(N2) | O ( N 2 ) O(N^2) O(N2) | O ( 1 ) O(1) O(1) | 稳定 |
选择排序 | O ( N 2 ) O(N^2) O(N2) | O ( N 2 ) O(N^2) O(N2) | O ( N 2 ) O(N^2) O(N2) | O ( 1 ) O(1) O(1) | 不稳定 |
插入排序 | O ( N ) O(N) O(N) | O ( N 2 ) O(N^2) O(N2) | O ( N 2 ) O(N^2) O(N2) | O ( 1 ) O(1) O(1) | 稳定 |
希尔排序 | O ( N ) O(N) O(N) | O ( N 1.3 ) O(N^{1.3}) O(N1.3) | O ( N 2 ) O(N^2) O(N2) | O ( 1 ) O(1) O(1) | 不稳定 |
快速排序 | O ( N l o g N ) O(NlogN) O(NlogN) | O ( N l o g N ) O(NlogN) O(NlogN) | O ( N 2 ) O(N^2) O(N2) | O ( l o g N − N ) O(logN - N) O(logN−N) | 不稳定 |
归并排序 | O ( N l o g N ) O(NlogN) O(NlogN) | O ( N l o g N ) O(NlogN) O(NlogN) | O ( N l o g N ) O(NlogN) O(NlogN) | O ( n ) O(n) O(n) | 稳定 |
堆排序 | O ( N l o g N ) O(NlogN) O(NlogN) | O ( N l o g N ) O(NlogN) O(NlogN) | O ( N l o g N ) O(NlogN) O(NlogN) | O ( 1 ) O(1) O(1) | 不稳定 |
计数排序 | O ( N + K ) O(N+K) O(N+K) | O ( N + K ) O(N+K) O(N+K) | O ( N + K ) O(N+K) O(N+K) | O ( N + K ) O(N+K) O(N+K) | 稳定 |
基数排序 | O ( d ( n + r ) ) O(d(n+r)) O(d(n+r)) | O ( d ( n + r ) ) O(d(n+r)) O(d(n+r)) | O ( d ( n + r ) ) O(d(n+r)) O(d(n+r)) | O ( r d + n ) O(rd+n) O(rd+n) | 稳定 |
计数排序中:K表示数字范围
基数排序中:r代表关键字基数,d代表长度,n代表关键字个数
三、冒泡排序
3.1 冒泡排序你了解吗?
答:冒泡排序的原理是(以升序为例):比较相邻的两个元素,如果前一个数比后一个数大,将二者交换。
3.2 冒泡排序时间复杂度怎么算?
答:冒泡排序每轮交换结束后,可以最少使得一个数字达到有序,因此最多执行 n − 1 n-1 n−1 轮后,一定可以排好序。最差时间复杂度 O ( N 2 ) O(N^2) O(N2)。
添加 f l a g flag flag 判断后,执行第一轮时,发现已经全局有序,直接跳出循环。因此最好时间复杂度为 O ( N ) O(N) O(N)。
平均时间复杂度为 O ( N 2 2 ) O(\frac{N^2}{2}) O(2N2) = O ( N 2 ) O(N^2) O(N2)
3.3 冒泡排序空间复杂度多少?
答:仅需要常数个临时变量,用于交换前后两数字时使用。因此空间复杂度为 O ( 1 ) O(1) O(1)
3.4 冒泡排序稳定吗?
答:是稳定的。
稳定与否指的是如果数组中有相同的元素,那么排序后有没有可能,在最终结果中,原始数组中不同索引的相同元素的顺序是不固定的。
这里比较拗口,但是我们可以这样理解,一个数组[1,2,5,5,4],有两个数字5,我们认为它们是不同的,不妨假设为[1,2, 5 1 5_1 51, 5 2 5_2 52,4]。用两个不同下标,区分这两个5。假设排序后有可能得到[1,2,4, 5 1 5_1 5