希尔排序

希尔排序

概述

希尔排序是插入排序的改进版,也称缩小增量排序。其核心思想是将原始数组按增量分成多个子序列,对每组进行插入排序,随后逐步缩小增量直至为1,最终完成整体排序。

常见的增量序列间隔选择方式

  1. Shell原始序列 :1 2 ... n / 4 n/4 n/4 n / 2 n/2 n/2 (n为原始数组长度)

  2. Hibbard序列 :1 3 7 ... 2 k − 1 2^k-1 2k−1

  3. Knuth序列 :1 4 13 ... ( 3 k − 1 ) / 2 (3^k-1)/2 (3k−1)/2

    最佳增量序列的的选择仍然是一个研究方向。

JavaScript实现

Shell序列

javascript 复制代码
function shellSort(list) {
    let n = list.length;
    let gap = n >> 1;
    while (gap) {
        // 分别处理以i开头,间隔gap的子序列
        for (let i = 0; i < gap; i++) {
            for (let j = i + gap; j < n; j += gap) {
                let k = j - gap;
                while (k >= 0 && list[k] > list[k + gap]) {
                    swap(list, k, k + gap);
                    k -= gap;
                }
            }
        }
        // 缩小gap
        gap = gap >> 1;
    }
    return list
}


for (let i = 0; i < 100; i++) {
    let list = generateList();
    console.log('origin list', list);
    let a = sort(clone(list)), b = shellSort(clone(list));
    console.log('sorte', a);
    console.log('shell', b);
    for (let j = 0; j < list.length; j++) if (a[j] !== b[j]) console.log('error');
    console.log('success')
}


// ---------------help----------------------

function clone(list) {
    return list.slice(0);
}

function swap(list, i, j) {
    var temp = list[i];
    list[i] = list[j];
    list[j] = temp;
}

function generateList() {
    let length = 10 + Math.ceil(Math.random() * 10);
    let list = [];
    while (length) {
        list.push(Math.ceil(Math.random() * 100));
        length--;
    }
    return list;
}

function sort(list) {
    list.sort((a, b) => a - b);
    return list;
}

Hibbard序列

javascript 复制代码
function shellSortByHibbard(list) {
    let n = list.length, K = Math.floor(Math.log2(n + 1));
    console.log('长度', n, 'K=', K);
    while (K) {
        let gap = Math.pow(2, K) - 1;
        // 分别处理以i开头,间隔gap的子序列
        for (let i = 0; i < gap; i++) {
            for (let j = i + gap; j < n; j += gap) {
                let k = j - gap;
                while (k >= 0 && list[k] > list[k + gap]) {
                    swap(list, k, k + gap);
                    k -= gap;
                }
            }
        }

        K--;
    }
    return list;
}

Knuth序列

javascript 复制代码
function shellSortByKnuth(list) {
    let n = list.length, K = Math.floor(Math.log(2 * n + 1) / Math.log(3));
    console.log('长度', n, 'K=', K);
    while (K) {
        let gap = (Math.pow(3, K) - 1) >> 1;
        // 分别处理以i开头,间隔gap的子序列
        for (let i = 0; i < gap; i++) {
            for (let j = i + gap; j < n; j += gap) {
                let k = j - gap;
                while (k >= 0 && list[k] > list[k + gap]) {
                    swap(list, k, k + gap);
                    k -= gap;
                }
            }
        }

        K--;
    }
    return list;
}
相关推荐
仿生狮子3 小时前
OpenAI 攻下千禧年难题之后,开发者似乎无动于衷
前端·数学·vibecoding
夏幻灵6 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
Lvan的前端笔记6 小时前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
三天不学习7 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194057 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
明月_清风8 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js
Csvn9 小时前
框架性能优化
前端
回眸&啤酒鸭11 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户693717500138411 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员11 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端