希尔排序的原理及实现--Java实现

首先呢,希尔排序又称“缩小增量排序”(Diminishing Increment Sort),是插入排序的优化。

希尔排序都对插入排序做了哪些优化呢?

如下:

  • 希尔排序在排序前:将一个序列分成了好几个序列
  • 在第一趟排序时:将这几个序列做插入排序。排序后,部分较大的数字往后靠,部分较小的数字往前靠
  • 在第二趟排序时:将这个序列又分了好几个序列做插入排序(但比第一次分的数要少,ps:如果第一次分5个,第二次可能就2个了)。排序后,部分较大的数字往后靠,部分较小的数字往前靠
  • 在第n趟排序时:将这个序列又分了好几个序列(直到剩下一个序列),从宏观上看,此序列就基本是有序的了。这时就用简单插入排序将数列直至已序

 

有点像归并排序,归并排序是将待排序的数组(递归的)分成两半,对这两部分分别排序,然后将结果归并起来,得到结果,体现了分治的思想。

希尔排序是有个gap值,这个排序的分组是隔gap个位置的两个元素分一组,也就是说相隔gap位置的元素必定是有序的,归并排序并没有这个规定。

当然这两个排序算法的时间复杂度都是O(nlogn)。

 

直观来说

如果一个数列有10个元素,我们第一趟的增量是5,第二趟的增量是2,第三趟的增量是1。

如果一个数列有18个元素,我们第一趟的增量是9,第二趟的增量是4,第三趟的增量是2,第四趟的增量是1

如果用一个序列来表示增量:{n/2,(n/2)/2...1},每次增量都除2

这张图解写得很清楚,搬运一下:

最后上一下代码(如果把上述原理理解的话,代码是很好理解的):

public static void shellSort(int[] arrays) {

        //增量step每次都除2
        for (int step = arrays.length / 2; step > 0; step /= 2) {

            //从增量那组开始进行插入排序,直至完毕
            for (int i = step; i < arrays.length; i++) {

                int j = i;
                //定义temp来保存i位置的元素,方便一会儿移动
                int temp = arrays[j];

                // j - step 就是代表与它同组隔壁的元素
                while (j - step >= 0 && arrays[j - step] > temp) {

                    arrays[j] = arrays[j - step];//大元素后移
                    j = j - step;
                }
                //直到找到合适位置,插入temp
                arrays[j] = temp;
            }
        }


    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值