用javascript 实现 希尔排序

394 阅读1分钟

一、简介:

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 优点:时间复杂度较低,执行效率还算OK, 空间复杂度低,内存消耗少
  • 缺点:不稳定

二、核心思想

  • 本质是插入排序的改进版
  • 根据步长,分组进行插入排序
  • 三层循环
  • 第一层循环控制分几次组,和步长
  • 里面的两层循环时控制插入排序的,看不懂的可以看我之前写的插入排序,友情提示,看不明白的你可以把普通插入排序看成步长为1

三、根据步长分组图

这里就以第一次分组为例,之后每次分组的步长为上次分组的步长除2,直到步长为1,步长不为整数时向下取整。

希尔排序.jpg

三、核心代码

代码地址:github.com/shubenwumin…

const shellSort = function (arr) {
  let length = arr.length;
  // 初始分组步长为数组长度除2,后续分组步长为上次步长除2
  let gap = Math.floor(length / 2);
  // 待插元素
  let current;
  // 已排序边界
  let boundary;
  // 此层循环控制分几次组及 每次分组的步长
  while(gap > 0) {
    // 从这里开始插入排序了
    for (let i = gap; i < length; i++) {
      current = arr[i];
      boundary = i - gap;
      for (boundary; boundary >= 0 && arr[boundary] > current; boundary -= gap) {
        arr[boundary + gap] = arr[boundary]
      }
      arr[boundary + gap] = current;
    }
    // 步长更新
    gap = Math.floor(gap / 2);
  }
  
  return arr;
}