插入排序(JS)

将左侧序列看成一个有序序列,每次将一个数字插入该有序序列。

插入时,从有序序列最右侧开始比较,若比较的数较大,后移一位。
平均时间复杂度:O(N^2)
最差时间复杂度:O(N^2)
空间复杂度:O(1)
排序方式:In-place
稳定性:稳定
/**
 * 基础插入排序 - 方法1
 * @param {*} arr 数组 [3, 1, 5, 4, 7, 6, 0, 2]
 * @returns sort-arr
 */
console.time('insertSort1');
var arr1 = [3, 1, 5, 4, 7, 6, 0, 2];
console.log('原数组', arr1);
var insertSort1 = arr => {
  let len = arr.length;
  if (len <= 1) return;
  for (let i = 1; i < len; i++) {
    let currentIndex = i;
    for (let j = i - 1; j >= 0; j--) {
      if (arr[j] > arr[currentIndex]) {
        [arr[j], arr[currentIndex]] = [arr[currentIndex], arr[j]];
        currentIndex = j;
      } else {
        break;
      }
    }
  }
  console.log('排序后数组', arr);
  return arr;
};
insertSort1(arr1);
console.timeEnd('insertSort1');
/**
 * 插入排序 - 方法2
 * 内循环 使用while 多个current空间声明 内循环完成才进行赋值
 * @param {*} arr 数组 [3, 1, 5, 4, 7, 6, 0, 2]
 * @returns sort-arr
 */
console.time('insertSort2');
var arr2 = [3, 1, 5, 4, 7, 6, 0, 2];
var insertSort2 = arr => {
  let len = arr.length;
  if (len <= 1) return;
  let prev, current;
  for (let i = 1; i < len; i++) {
    prev = i - 1;
    current = arr[i];
    while (prev >= 0 && arr[prev] > current) {
      arr[prev + 1] = arr[prev];
      prev--;
    }
    arr[prev + 1] = current;
  }
  console.log('排序后数组', arr);
  return arr;
};
insertSort2(arr2);
console.timeEnd('insertSort2');
/**
 * 插入排序 - 方法3 (推荐使用该方法 也好理解)
 * 内循环 使用while 这个算法相对我觉得最好理解 前面大于后面 则两个元素对调位置
 * @param {*} arr 数组 [3, 1, 5, 4, 7, 6, 0, 2]
 * @returns sort-arr
 */
console.time('insertSort3');
var arr3 = [3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2];
var insertSort3 = arr => {
  let len = arr.length;
  if (len <= 1) return;
  let prev;
  for (let i = 1; i < len; i++) {
    prev = i - 1;
    while (prev >= 0 && arr[prev] > arr[prev + 1]) {
      [arr[prev], arr[prev + 1]] = [arr[prev + 1], arr[prev]];
      prev--;
    }
  }
  console.log('排序后数组', arr);
  return arr;
};
insertSort3(arr3);
console.timeEnd('insertSort3');
/**
 * 插入排序 - 方法4 (当数据量大时 采用二分法效率提升)
 * 内循环 使用while 
 * 当左边元素存在大量数据时 采用上面的算法 则需要一直对比
 * 针对左边元素 采用二分法 每次二分法 则判断目标元素属于左边还是右边 这样就节约了去每个元素对比
 * @param {*} arr 数组 [3, 1, 5, 4, 7, 6, 0, 2]
 * @returns sort-arr
 */
console.time('insertSort4');
var arr4 = [3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2,3, 1, 5, 4, 7, 6, 0, 2];
var insertSort4 = arr => {
  let len = arr.length;
  if (len <= 1) return;
  let key, left, right, middle;
  for (let i = 1; i < len; i++) {
    key = arr[i];
    left = 0;
    right = i - 1;
    while (left <= right) {
      middle = Math.ceil((left + right) / 2); // 针对非正整数处理
      if (arr[middle] > key) right = middle - 1;
      else left = middle + 1;
    }
    for (let j = i - 1; j >= left; j--) {
      arr[j + 1] = arr[j];
    }
    arr[left] = key;
  }
  console.log('排序后数组', arr);
  return arr;
};
insertSort4(arr4);
console.timeEnd('insertSort4');

参考链接:
插入排序参考1
插入排序参考2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值