在校招面试中,排序算法是经常被问到的。排序算法又比较多,很容易遗忘和混淆。建议收藏起来,面试前可以快速过一遍。正所谓:临阵磨枪,不快也光。
重复地遍历要排序的数组,一次比较前后两个数,如果它们的顺序错误就把它们交换过来。因为越小的数会在交换过程中慢慢“浮”到数组的顶端,所以被称作冒泡排序。具体过程如下:
通过一次排序将待排序的数组分隔成两个子数组,一个子数组的数都比另一子数组的数小,则可分别对这两部分继续进行排序,最后使整个数组都有序。具体过程如下:
在要排序的数组中,先把第1个位置数看成是一个有序的子数组,然后从第2个数逐个进行插入,直到整个数组有序为止。
希尔排序是插入排序的升级版本,先把整个数组分割为几个子数组进行插入排序,当整个数组中的数基本有序时,再对整个数组进行一次插入排序。具体过程如下:
在要排序的数组中,首先找出最小的一个数和第1个位置的数交换;然后在剩下的数中再找最小的数和第2个位置的数交换;依次类推,直到倒数第二个数和最后一个数进行比较为止。
堆排序是利用堆这种数据结构所设计的一种排序算法。堆排序可以分为两个阶段:堆的构造阶段、下沉排序阶段。
在堆的构造阶段中,我们将原始数组重新组织安排进一个堆中;然后在下沉排序阶段,我们从堆中按递减顺序取出所有元素并得到排序结果。
把两个有序的数组合并成一个有序的数组。也就是说,把要排序的数组分成两个子数组,当每个子数组是有序的时候,再把这两个子数组合并成为整个数组,也叫做二路归并排序。如果把要排序的数组分成多个子数组,就叫做多路归并排序。
计数排序使用了一个额外的数组 ,其中第i个数是待排序数组中数等于i的个数。然后根据这个额外的数组来将待排序数组中的数排到正确的位置。
桶排序是将待排序数组分到有限数量的桶里,然后再使用桶排序或者其他的排序算法对每个桶再分别进行排序。
基数排序是把整数按位数切割成不同的数字,然后按每个位数分别比较。按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。
排序算法 | 时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O(n²) | O(n²) | O(n) | O(1) | √ |
快速排序 | O(n log n) | O(n²) | O(n log n) | O(log n) | × |
插入排序 | O(n²) | O(n²) | O(n) | O(1) | √ |
希尔排序 | O(n log n) | O(n²) | O(n) | O(1) | × |
选择排序 | O(n²) | O(n²) | O(n²) | O(1) | × |
堆排序 | O(n log n) | O(n log n) | O(n log n) | O(1) | × |
归并排序 | O(n log n) | O(n log n) | O(n log n) | O(n) | √ |
计数排序 | O(n + k) | O(n + k) | O(n + k) | O(n + k) | √ |
桶排序 | O(n + k) | O(n + k) | O(n²) | O(n + k) | √ |
基数排序 | O(n * k) | O(n * k) | O(n * k) | O(n + k) | √ |