# 希尔排序
希尔排序的思路是消除数组中的逆序对,是在插入排序算法上的改良,其根据一定的规则选取增量序列 D(k)·D(k-1)·D(k-2)···1,增量序列的最后一项必须是 1,分别以对 D(k)至 1 为间距对数组进行插入排序(因为采取了对 D(k-1)为间距的插入排序之后并不会使得 D(k)为间距进行插入排序之后的结果变坏这是希尔排序的理论基础),此刻数组会变得大致有序,最后再进行一次(间距 D 为 1)插入排序,从而使得数组有序。
用通俗易懂的语言描述就是,举个例子,我先对数组使用一次 4 (D(k))为间距的插入排序,得到一个结果,在这个结果上以 2(即 D(k-1), 这个间距完成之后,并不会让之前 4 为间距的插入排序的结果变坏) 为间距再进行一次插入排序,又的到一个结果,最后,我对数组使用一次纯粹(因为间隔是 1,所以说它纯粹)的插入排序。
# 排序过程
# 算法实现
/**
* 对数组进行希尔排序
* @param {Array<number>} arr 需要进行排序的数组
*/
function shellSort(arr) {
// 选取 N/2->N/4->N/8->···->1的增量序列
for (let D = Math.floor(arr.length / 2); D >= 1; D = Math.floor(D / 2)) {
// 以间距D对数组进行插入排序
for (let i = D; i < arr.length; i++) {
let cur = arr[i];
let j = i;
// 注意这儿需要取到等于
while (j >= D && arr[j - D] > cur) {
arr[j] = arr[j - D];
j -= D;
}
arr[j] = cur;
}
}
}
# 复杂度与稳定性
希尔排序的时间复杂度是O(n*logn)
,是不稳定
的排序算法。
希尔排序的算法复杂度的分析是个世纪难题,其算法的时间复杂度跟你选择的增量序列有关系,有兴趣的朋友可以自行了解这部分的内容。