在校招面试中,排序算法是经常被问到的。排序算法又比较多,很容易遗忘和混淆。建议收藏起来,面试前可以快速过一遍。正所谓:临阵磨枪,不快也光。

冒泡排序

重复地遍历要排序的数组,一次比较前后两个数,如果它们的顺序错误就把它们交换过来。因为越小的数会在交换过程中慢慢“浮”到数组的顶端,所以被称作冒泡排序。具体过程如下:

  1. 比较相邻的数,如果第一数个比第二数个大,就交换它们两个。
  2. 对每一对相邻数作同样的上述操作,从开始第一对到结尾的最后一对,这样在最后的数就是最大的数。
  3. 针对所有的数重复上面的步骤,除了最后一个数(因为最后一个数已经是最大的了)。
  4. 对越来越少的数重复步骤上面的步骤,直到整个数组排序完成。

快速排序

通过一次排序将待排序的数组分隔成两个子数组,一个子数组的数都比另一子数组的数小,则可分别对这两部分继续进行排序,最后使整个数组都有序。具体过程如下:

  1. 选择一个基准数,通常是数组的第1个数。
  2. 重新排序数组,所有数比基准数小的挪放在基准数前面,所有数比基准数大的挪在基准数的后面。
  3. 在这个排序之后,该基准数就处于数组有序后的正确位置。
  4. 把基准数前后两个子数组,按照上述步骤继续排序,直到整个数组有序。

插入排序

在要排序的数组中,先把第1个位置数看成是一个有序的子数组,然后从第2个数逐个进行插入,直到整个数组有序为止。

希尔排序

希尔排序是插入排序的升级版本,先把整个数组分割为几个子数组进行插入排序,当整个数组中的数基本有序时,再对整个数组进行一次插入排序。具体过程如下:

  1. 选择一个增量序列t1,t2,…,tk,其中ti > tj,tk = 1。比如:40、13、4、1。
  2. 按增量序列个数k,对序列进行k次插入排序。
  3. 每次插入排序,根据对应的增量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)

最后,谢谢你这么帅,还给我点赞