在校招面试中,排序算法是经常被问到的。排序算法又比较多,很容易遗忘和混淆。建议收藏起来,面试前可以快速过一遍。正所谓:临阵磨枪,不快也光。
冒泡排序
重复地遍历要排序的数组,一次比较前后两个数,如果它们的顺序错误就把它们交换过来。因为越小的数会在交换过程中慢慢“浮”到数组的顶端,所以被称作冒泡排序。具体过程如下:
- 比较相邻的数,如果第一数个比第二数个大,就交换它们两个。
- 对每一对相邻数作同样的上述操作,从开始第一对到结尾的最后一对,这样在最后的数就是最大的数。
- 针对所有的数重复上面的步骤,除了最后一个数(因为最后一个数已经是最大的了)。
- 对越来越少的数重复步骤上面的步骤,直到整个数组排序完成。
快速排序
通过一次排序将待排序的数组分隔成两个子数组,一个子数组的数都比另一子数组的数小,则可分别对这两部分继续进行排序,最后使整个数组都有序。具体过程如下:
- 选择一个基准数,通常是数组的第1个数。
- 重新排序数组,所有数比基准数小的挪放在基准数前面,所有数比基准数大的挪在基准数的后面。
- 在这个排序之后,该基准数就处于数组有序后的正确位置。
- 把基准数前后两个子数组,按照上述步骤继续排序,直到整个数组有序。
插入排序
在要排序的数组中,先把第1个位置数看成是一个有序的子数组,然后从第2个数逐个进行插入,直到整个数组有序为止。
希尔排序
希尔排序是插入排序的升级版本,先把整个数组分割为几个子数组进行插入排序,当整个数组中的数基本有序时,再对整个数组进行一次插入排序。具体过程如下:
- 选择一个增量序列t1,t2,…,tk,其中ti > tj,tk = 1。比如:40、13、4、1。
- 按增量序列个数k,对序列进行k次插入排序。
- 每次插入排序,根据对应的增量ti,将数组分割成几个子序列,分别对各子数组进行插入排序。当最后增量为1 时,对整个数组作进行一次插入排序。
选择排序
在要排序的数组中,首先找出最小的一个数和第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) | √ |
最后,谢谢你这么帅,还给我点赞和关注。
网友评论