Contents

排序算法之插入排序

排序算法之插入排序

了解排序法是学习算法的必经之路. 所谓排序法, 就是将一堆没有排序过的数字由小到大 (或大到小) 排列好的算法

大致了解何谓排序法后, 现在我们来介绍最简单的排序法: 插入排序

插入排序 (Insertion Sort)

插入排序是一种最简单直观的排序算法, 它的工作原理是通过构建有序序列, 对于未排序数据, 在已排序序列中从后向前扫描, 找到相应位置并插入

基本来说, 插入排序只需要重复执行两个步骤, 分别是:

1. 从 [未排序好的数字] 取出第一个与 [已排序好的数字] 比较
2. 如果 [已排序好的数字] 大于 [未排序好的数字], 则将 [已排序好的数字] 后移一位, 否则直接插入

算法实现:

function insertionSort(arr: number[]): number[] {
  // 默认第一个元素为有序, 或者为参考点
  // 每次迭代时, 从 j 到 arr.length 所代表的就是还未排序的部分
  for (let j = 1; j < arr.length; j++) {
    // 取出当前元素 key
    const key = arr[j];
    // 从 0 ~ i 的部分即为已经排序的部分, 也称为(循环不变式)
    let i = j - 1;
    // 从已经排序的部分中找到比 key 小的元素
    while (i >= 0 && arr[i] > key) {
      // 如果找到比 key 更大的数了, 则将当前已经排序的元素与下一个元素的位置进行交换, 也就是滞后一位
      arr[i + 1] = arr[i];
      // 并且使 i 向前移动一位
      i--;
    }
    // 如果没有找到比 key 更小的数了, 则将 key 放到最后一个比它小的元素之前的位置
    arr[i + 1] = key;
  }
  return arr;
}

复杂度分析

时间复杂度 O(N ** 2)

最坏的情况是待排序数组完全逆序, 也就是每一次插入都要和有序集合中的所有元素进行比较, 插入第二个元素时需要与前 1 个元素进行比较, 以此类推, 插入前 N 个元素需要与前 N - 1 个元素比较: 1 + 2 + 3 + ... + (N - 1), 结果为: (N − 1) ∗ N / 2, 也即为: O(N \*\* 2)

空间复杂度 O(1)

空间复杂度未借助额外的空间, 空间复杂度即为: O(1)