一、简介:
- 时间复杂度:O(nlogn)
- 空间复杂度:O(1)
- 稳定性:不稳定
- 优点:时间复杂度较低,执行效率还算OK, 空间复杂度低,内存消耗少
- 缺点:不稳定
二、核心思想
- 本质是插入排序的改进版
- 根据步长,分组进行插入排序
- 三层循环
- 第一层循环控制分几次组,和步长
- 里面的两层循环时控制插入排序的,看不懂的可以看我之前写的插入排序,友情提示,看不明白的你可以把普通插入排序看成步长为1
三、根据步长分组图
这里就以第一次分组为例,之后每次分组的步长为上次分组的步长除2,直到步长为1,步长不为整数时向下取整。
三、核心代码
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;
}