排序算法之插入排序

205 阅读2分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

介绍

插入排序是依次取出一个数,并和前面的数比较大小,插入到合适的位置。

就好像我们手动整理一副乱序的扑克,先将第2张和第1张比,如果比第1张小,则放在它前面;然后将第3张和第2张比,如果比它小,再和第1张比,如果比它大,则插入到第2和第1张中间。

sort-ins.gif

实现

js代码实现如下:

function insertSort(array) {
  const { length } = array;
  // 这里从第2个数开始往前比
  for (let i = 1; i < length; i++) {
    let j = i;
    // 后续计算的过程会修改i位置的值,因此需要保存一个临时变量
    const temp = array[i]
    while (j > 0 && array[j - 1] > temp) {
      // 如果前一个数小于待插入的数,则将前一个数后移一位
      array[j] = array[j - 1]
      j--
    }
    // 最后j就是需要插入的位置,这个位置上原本的数已经后移了一位
    array[j] = temp
  }
  return array;
}

这个算法实现的时候需要注意减少赋值次数:

比如3,5,1,4,2。当待插入数为1时,1与5比较,1<5,则对5后一个位置赋值5,但不需要此时就将1插入到5原先的位置(不需要交换1和5的位置)。之后1与3比较,1<3,则继续将3后一个位置赋值为3,这样通过向后赋值,完成数组的位移。

插入算法的执行过程可以参考下图:

image.png

插入排序的时间复杂度O(n2)O(n^2),与冒泡排序一样,在实践中也只应用于小型数组,但是它的性能要比冒泡排序更好。

为什么说插入排序优于冒泡排序

插入排序和冒泡排序都是稳定排序,而插入排序比冒泡更优的点在于赋值次数。

同样对3,5,1,4,2进行排序:

冒泡排序比较5和1时会直接交换:3,1,5,4,2,通常需要3次赋值。

// 交换x和y
temp = x;
x=y;
y=temp;

而插入排序比较5和1时,仅做一次赋值:3,5,5,4,2。