排序算法之插入排序

个人主页:爱吃炫迈
系列专栏:数据结构与算法
‍座右铭:快给我点赞赞

文章目录

  • 1. 插入排序
  • 2. 算法原理
  • 3. 算法思路
  • 4. 算法实现
  • 5. 算法性能分析
  • 6. 稳定性分析
  • 总结


1. 插入排序

  • 插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法 。
  • 插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表

动图演示

排序算法之插入排序_第1张图片

学习插入排序时,可以代入一下我们正在打扑克的场景~~~

  • 插入排序的工作方式像斗地主时排序一手扑克牌。
  • 开始时,我们的左手为空并且桌子上的牌面向下。
  • 然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置
  • 为了找到一张牌的正确位置,我们从右到左将它与已在左手中的每张牌进行比较
  • 拿在左手上的牌总是排序好的,右手拿的牌是桌子上牌堆中顶部的牌

2. 算法原理

  • 插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的;(称为有序表,剩余未排的数称为无序表)
  • 现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入数后的这个序列也是排好顺序的
  • 按照此法对所有元素进行插入,直到整个序列排为有序的过程,称为插入排序。

3. 算法思路

排序算法之插入排序_第2张图片

案例演示

用插入排序算法实现5,2,4,6,1,3的升序排序

开始排序

有序表 无序表
5 2, 4, 6, 1, 3

第一趟:此时有序表是5,无序表是2, 4, 6, 1, 3

后往前遍历有序表:

  1. 将2和5进行比较,结果5>2;
  2. 此时将5向后移一个位置,2插入在5的前面;
  3. 得到新的有序表2,5;新的无序表4,6,1,3
有序表 无序表
2,5 4, 6, 1, 3

第二趟:此时有序表是2, 5,无序表是4, 6, 1, 3

后往前遍历有序表:

  • 将4和5进行比较,结果5>4;此时将5向后移一个位置,4插入在5的前面;
  • 将4和2进行比较,结果4>2;此时4的位置不用在移动
  • 得到新的有序表2, 4, 5,新的无序表6, 1, 3
有序表 无序表
2,4,5 6, 1, 3

第三趟:此时有序表是2,4,5,无序表是6, 1, 3

后往前遍历有序表:

  • 将6和5进行比较,结果5>6;此时将6直接插入到5的后面位置;
  • 得到新的有序表2, 4, 5,6,新的无序表1, 3
有序表 无序表
2,4,5,6 1, 3

第四趟:此时有序表是2,4,5,6,无序表是 1, 3

后往前遍历有序表:

  • 将1和6进行比较,结果6>1;此时将1插入到6的前面;
  • 将1和5进行比较,结果5>1;此时将1插入到5的前面;
  • 将1和4进行比较,结果4>1;此时将1插入到4的前面;
  • 将1和2进行比较,结果2>1;此时将1插入到2的前面;
  • 得到新的有序表1,2, 4, 5,6,新的无序表 3
有序表 无序表
1,2, 4, 5,6 3

第五趟:此时有序表是1,2, 4, 5,6,无序表是 3

后往前遍历有序表:

  • 将3和6进行比较,结果6>3;此时将3插入到6的前面;
  • 将3和5进行比较,结果5>3;此时将3插入到5的前面;
  • 将3和4进行比较,结果4>1;此时将3插入到4的前面;
  • 将3和2进行比较,结果3>2;此时3的位置不用移动;
  • 得到新的有序表1,2, 3,4, 5,6,
有序表
1, 2, 3, 4, 5, 6

排序完成啦~~撒花~


4. 算法实现

function insertSort(arr) {
        let curIndex, temp;
        // 外层循环是遍历无序表
        for (var i = 1; i < arr.length; i++) {
          curIndex = i;
          // 内层循环是从右向左依次遍历有序表
          for (var j = i - 1; j >= 0; j--) {
            // 有序表中若有大于无序表中进行比较的数时,交换位置
            if (arr[j] > arr[curIndex]) {
              temp = arr[curIndex];
              arr[curIndex] = arr[j];
              arr[j] = temp;
              curIndex = j;
            } else {
              break;
            }
          }
        }
        return arr;
      }
      var arr = [5, 2, 4, 6, 1, 3];
      var arrSorted = insertSort(arr);
      console.log(arrSorted); //输出1,2,3,4,5,6

5. 算法性能分析

  • 时间复杂度

最优

在插入排序中,当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较N- 1次,时间复杂度为O(n)

最坏

最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为O(n^2)

平均

平均来说,A[1…j-1]中的一半元素小于A[j],一半元素大于A[j]。插入排序在平均情况运行时间与最坏情况运行时间一样,是输入规模的二次函数

  • 空间复杂度

插入排序的空间复杂度为常数阶O(1)


6. 稳定性分析

如果待排序的序列中存在两个或两个以上具有相同关键词的数据,排序后这些数据的相对次序保持不变,即它们的位置保持不变,通俗地讲,就是两个相同的数的相对顺序不会发生改变,则该算法是稳定的;如果排序后,数据的相对次序发生了变化,则该算法是不稳定的。关键词相同的数据元素将保持原有位置不变,所以该算法是稳定的。


总结

希望我的文章能对你学习选择排序有所帮助!

你可能感兴趣的:(数据结构与算法,排序算法,算法,数据结构)