Java排序系列之希尔排序

前言:
Java排序之希尔排序
简介:
俺们今天来聊聊希尔排序这个排序算法,好,今天这个排序算法的名字啊,它跟该算法的原理呀,那完全没有一点关系!开个玩笑,希尔排序之所以叫希尔排序,是因为设计这个算法的人名字叫希尔(Donald Shell),因此就以他的名字命名。但是哈,Metzner本人却说,“我没有为这种算法做任何事,我的名字不应该出现在算法的名字中。”这个…对吧,还挺谦虚的。其实该算法还有一个名字叫缩小增量排序,这下就与算法原理有关了。好了,开始今天的干货。希尔排序呢,是基于插入排序进行的改进,它是基于插入排序以下两点特性进行的改进:1)插入排序对几乎有序的数据进行排序时,效率高。2)插入排序每次只能将数据移动一位,低效。
原理:
1)先取一个小于数组长度n(一般先取数组长度的一半)的整数gap1作为第一个增量,把数组分成多个组,分组的规则是所有的距离为gap1倍数的数据放在一起(举个例子:数组[1,2,3,4,5],取增量为2,则分成[1,3,5]和[2,4]),然后对每组数据使用插入排序,插入排序咱们之前讲过(Java排序系列之插入排序),这里就不说了;
2)然后取增量gap2<gap1,重复以上步骤;
3)直到增量等于0。
上代码,哦不,上个图先:
在这里插入图片描述
这图网上找的吗?是的,我不想画。
在这里插入图片描述
接下来使用Java实现该算法:

void mergeSort(int[] arr) {
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
        for (int i = 0; i < gap; i++) {
            insertSort(arr, gap, i);
        }
    }

}

//对插入排序的一些细微改动
void insertSort(int[] arr, int gap, int pos) {
    for (int i = pos + gap; i < arr.length; i += gap) {
        int temp = arr[i], index = i - gap;
        while (index >= pos && temp < arr[index]) {
            arr[index + gap] = arr[index];
            index -= gap;
        }
        arr[index + gap] = temp;
    }
}

看起来代码还是挺简单的哈,但是啊,这个改动了的插入排序差点没理清楚,估计是昨晚没睡好。
好了,本节目的分析算法时间复杂度环节来了:
这个希尔排序的算法时间复杂度呢,太难了,分析不太动,就简单总结一下,希尔排序的执行时间依赖于增量序列;同时呢,Shell排序的时间性能优于直接插入排序,主要一点是在希尔排序开始时,增量较大,分组较多,每组的数据少,各组插入排序较快,后来增量gap缩小,分组减少,但是每个分组比较接近于有序状态,所以新的一趟排序过程也较快。还有一个就是,有人通过大量的实验,给出了较好的结果:当n较大时,比较和移动的次数约在n的1.25到2次方之间。总之大家要记住希尔算法优于插入排序的原因,至于复杂度,了解就行。
稳定性呢,它是不稳定的,虽然插入排序是稳定,但是希尔排序一次使用了多个插入排序,就有可能导致不稳定,比如,[2,2,1,3]数组,第一趟希尔排序之后,第一个2就到了第三个位置,然而原先的第二个2位置没变,依然在第二个位置,但是相对位置却变了,所以希尔排序是不稳定的排序算法。
总结
希尔排序时间复杂度在n的1.25到2次方之间,它又名缩小增量排序,算法的快慢与增量的选择有关,它的效率是高于插入排序的,但是呢,它不是稳定的排序算法。
好了,希尔排序就讲到这里,接下来会对其它的排序算法持续更新。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值