希尔排序

希尔排序

希尔排序插入排序的改进版本,弥补了插入排序在某种情况下的缺点
列如:当长度为100的数组,下标0~79为有序区域,此时我们用下标为80的元素去跟它前面的有序区域的元素比较大小,恰巧我们的下标为80的元素是100个元素中最小的,本应在下标为0的位置,如图

在这里插入图片描述
本列中下标为80的元素为1,那么他前面的有序区域里面的80个元素都要向后移一个位置,此状非常影响排序性能。
因此,我们要想办法尽可能让小的靠前,让大的靠后,这样就可以避免上图情况,这就是希尔排序要解决的问题。
希尔排序也叫缩小增量排序,它通过先设置一个增量n,大小为数组长度的一半,再将间隔为n的作为一组,然后对每组内部的元素进行从小到大的插入排序;然后再将n缩小一半,再次进行分组插入排序,直到增量n为1,因为增量为1时,所有元素都是同一组了。

//----------------分割线------------------

为了方便大家理解,我用一个例子来展示一个完整的希尔排序过程,首先数据的初始状态如图所示,这里为了更好地体现希尔排序的优点,我特地把值较大的元素放到了靠左的位置,把值较小的元素放到了靠右的位置
在这里插入图片描述
数组长度为8,增量 n=8/2 ,间隔n为一组;数组分组情况如下(同色为一组):
在这里插入图片描述
每组进行小到大的插入排序,结果如下:
在这里插入图片描述
此时增量为4 增量(n)不为1,继续增量(n)=n /2 ,间隔n为一组;数组分组情况如下(同色为一组):
在这里插入图片描述
每组进行小到大的插入排序,结果如下:
在这里插入图片描述
此时增量为2 增量(n)不为1,继续增量(n)=n /2 ,间隔n为一组;数组分组情况如下(同色为一组):
略。。。。。。。。。。。。。。
每组进行小到大的插入排序,结果如下:
在这里插入图片描述
动图演示
在这里插入图片描述
了解完了希尔排序的实现过程,我们现在用代码来封装一下:

function shellSort(arr) {
    // 1. 获取数组长度
    let length = arr.length

    // 2.获取初始的间隔长度
    let interval = Math.floor(length / 2)

    // 3. 不断地缩小间隔的大小,进行分组插入排序
    while(interval >= 1) {

        // 4. 从 arr[interval] 开始往后遍历,将遍历到的数据与其小组进行插入排序
        for(let i = interval; i < length; i++) {
            let temp = arr[i]
            let j = i
            while(arr[j - interval] > temp && j - interval >= 0) {
                arr[j] = arr[j - interval]
                j -= interval 
            }

            arr[j] = temp           
        }

        // 5. 缩小间隔
        interval = Math.floor(interval / 2)
    }

    return arr
}

上述情况中,希尔排序最坏情况下的时间复杂度为O(n²)。其实希尔排序的时间复杂度跟增量也有关系,我们上面是通过数组长度一直取一半获取的增量,其实还有一些别的增量规则,可以使得希尔排序的效率更高,例如Hibbard增量序列、Sedgewick增量序列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值