插入排序-希尔排序

希尔排序是插入排序的一种,有关插入排序可以移步:直接插入排序
希尔排序是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。

排序比较值相同时,前后位置不发生改变,则为稳定排序算法,反之为非稳定排序算法。

设计思想

希尔排序又称为缩小增量排序,基本思想是分组的直接插入排序。由直接插入排序算法分析可知,若数据序列越接近有序,则时间效率越高;再者,当n(待排序长度)较小时,时间效率也高。希尔排序正是基于这两点对直接插入排序算法进行的优化:

  1. 将一个数据序列分为若干组,每组由若干相隔一段距离(称为增量)的元素组成,在一个组内采用直接插入排序算法进行排序。
  2. 增量初值通常为数据序列长度的一半,以后每趟增量减半,最后值为1。随着增量逐渐减小,组内元素个数增加,数据序列接近有序。

代码实现

序列:{38,55,65,97,27,76,27,13,19},序列长度为9,增量delta初值为4,序列分为4组进行直接插入排序,之后每趟增量以减半规律变化。经过3轮完成排序。

    public static void shellSort(int[] keys) {
        //①若干趟,控制增量每趟减半
        for (int delta = keys.length / 2; delta > 0; delta /= 2) {
            //②一趟分为若干组,每组直接插入排序
            for (int i = delta; i < keys.length; i++) {
                //keys[i]是当前待插入元素
                int temp = keys[i], j;
                //③组内直接插入排序,寻找插入位置
                for (j = i - delta; j >= 0 && temp < keys[j]; j -= delta) {
                    //每组元素相距delta远
                    keys[j + delta] = keys[j];
                }
                keys[j + delta] = temp; //插入元素
            }
            System.out.print("delta = " + delta + "\t");
            printKeys(keys);
        }
    }

运行结果

初始数组:
38  55  65  97  27  76  27  13  19  
delta = 4	19  55  27  13  27  76  65  97  38  
delta = 2	19  13  27  55  27  76  38  97  65  
delta = 1	13  19  27  27  38  55  65  76  97  

希尔排序算法共有三重循环:

  1. 最外层循环①for语句以增量delta变化控制进行若干趟扫描,delta初值为序列长度 n/2,以后每趟减半,直至1.
  2. 中间循环for语句进行每一趟扫描,序列分为delta组,每组由相距delta远的n/delta个元素组成,每组元素分别进行直接插入排序。
  3. 最内层循环for语句进行一组直接插入排序,将一个元素keys[i] 插入到其所在组前面的排序子序列中。

算法分析

希尔排序算法增量的变化规律有多种方案。上述增量减半是一种可行方案。一旦确定增量的变化规律,则一个数据序列的排序趟数就确定了。初始当增量较大时,一个元素与较远的另一个元素进行比较,移动距离较远;当增量逐渐减小时,元素比较和移动距离较近,数据序列则接近有序。最后一次,再与相邻位置元素比较,决定排序的最终位置。

  • 希尔排序算法的时间复杂度分析比较复杂,实际所需的时间取决于具体的增量序列,网上说法众多,最差情况为O(n^2)
  • 希尔排序算法的空间复杂度为O(1)
  • 因为分组进行比较,相同值可能会错过比较机会,所以希尔排序不稳定
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aotulive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值