算法——希尔排序

希尔排序是插入排序的一种高效改进版,通过设置间隔序列减少元素移动次数,提高排序效率。希尔排序的基本思想是,先用较大的间隔进行部分排序,然后逐渐减小间隔,直到间隔为1,完成最终的插入排序。尽管最坏情况时间复杂度仍为O(n^2),但在实际应用中,希尔排序通常表现出优于其他O(n log n)算法的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

希尔排序

希尔排序是插入排序的一种高效的改进版,并且效率比插入排序要更快,因为它突破了时间复杂度为O(n^2的限制)。由于希尔排序是基于插入排序的,所以有必要回顾一下插入排序:

插入排序的问题:

1,假设一个很小的数据项在很靠近右端的位置上,这里本来应该是较大的数据项的位置。

2,把这个小数据项移动到左边的正确位置,那么所有的中间数据项都必须向右移动一位。

3,因此我们通常认为插入排序的时间复杂度为O(n^2)。

4,如果有某种方式,不需要一个个移动所有中间的数据项,就能把较小的数据项移动到左边,那么这个算法的执行效率就会有很大的改进。

希尔排序的思路:

以下图为例。

在这里插入图片描述

1,我们先让间隔为5的数字进行一个比较并进行排序,那么排序后的新序列,一定可以让每个数字距离自己的正确位置更近一步。

2,紧接着我们再让间隔为3的数字进行一个比较并进行排序,那么排序后的新序列,一定可以让每个数字距离自己的正确位置又更近一步。

3,最后,我们再让间隔为1的数字进行,也就是正确的插入排序了。

但是这里有一个问题就是如何去选择我们的一个间隔呢也就是增量呢?

希尔在自己原稿中的做法是:他建议的初始间隔为N/2,简单的把每趟排序分成两半,也就是说,对于N=100的数组,增量间隔序列为:50,25,12,6,3,1。而这个做法的好处在于不需要在开始排序前为找合适的增量再去进行其它的计算。

当然也可以了解一下其它的两种计算增量的方法。

1,Hibbard增量序列:增量的算法为2^k - 1,也就是1,3,5,7…等等,而这种增量的最坏复杂度为O(N3/2),猜想的平均复杂度为O(N5/4),但是目前尚未被证明。

2,Sedgewick增量序列:这种增量的最坏复杂度为O(N/4/3),平均复杂度为O(N/7/6),但是目前也未被证明。

function shellSort(arr) {
    //根据长度计算增量
    let gap = Math.floor(arr.length / 2);

    //根据gap的不断减小从而不断进行循环
    while (gap >= 1) {
        //以gap为间隔进行分组,然后就是插入排序的思路了
        for (let i = gap; i < arr.length; i++) {
            let temp = arr[i];
            let j = i;

            while (arr[j - gap] > temp && j > gap - 1) {
                arr[j] = arr[j - gap];
                j -= gap;
            }
            arr[j] = temp;
        }
        //重新计算新的间隔
        gap = Math.floor(gap / 2);
    }
    return arr;
}

console.log(shellSort([1, 3, 2, 6, 5, 4]));

希尔排序的效率:最坏的情况下时间复杂度为O(n^2),但是通常情况下都好于它,甚至在合适的增量以及数量的情况下,它比快速排序还好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值