java算法详解——希尔排序

  • 希尔排序通过加大插入排序元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项能够大幅度移动,当这些数据项过一趟序之后,希尔排序算法减少数据项的间隔再进行排序。依次进行下去,进行这些排序时数据项之间的间隔被称为增量。
  • 假设增量为d下面采用图解 就可以知道具体的详解
    图片采用知乎上面的图片
    假设数组是
    在这里插入图片描述
    第一趟希尔排序,设增量d=5
    在这里插入图片描述第一趟就有了 五个数组 【11,16,31】,【23,25】,【12,36】,【9,30】,【18,47】
    第二趟希尔排序,增量d=3
    在这里插入图片描述第二趟就有了三个数组【9,11,25,47】,【18,23,31,36】,【12,16,30】
    第三趟希尔排序,增量d=1
    在这里插入图片描述
    排序完成 ,每次都采用的插入排序,例如第一次取出来的数组是【16,11,31】采用插入排序后的是【11,16,31】一次计算就会出现第一次希尔排序后出现的五个数组
    下面是java代码
    @Test
    public void shellSort() {
//        增量每次都是/2
        int[] arr = {43, 32, 1, 34, 61, 12, 52, 39, 18, 17, 90, 30, 99, 67, 83, 2, 34, 53, 61, 47, 83, 32};
        for (int step = arr.length / 2; step > 0; step /= 2) {
//从增量那组开始进行插入排序,直到完毕
            for (int i = step; i < arr.length; i++) {
//                其中i-step就是上一个元素 如step是本节点的话 i-step就是上一个节点
                if (arr[i] < arr[i - step]) {
//                    将本节点的数据先放到一个临时位置
                    int temp = arr[i];
//                    上一个节点的位置k
                    int k = i - step;
//                    采用插入排序的算法
                    while (k >= 0 && arr[k] > temp) {//当还有多余的节点并且本节点的数据小于上一个节点 就会进入循环
//                        两个数据交换 上一个节点的数据等于本节点的数据
                        arr[k + step] = arr[k];
//
                        k -= step;
                    }
//                    将本节点的临时位置中的数据拿出来,从新赋值新的节点中
                    arr[k + step] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }

输出
在这里插入图片描述
严格意义上的希尔排序

  @Test
    public void shellSort1() {
        //        增量每次都是/2
        int[] a = {43, 90, 1, 34, 61, 12, 52, 39, 18, 17};
// 数组的长度
        int n = a.length;
//  首先是每次除以二 按照希尔排序的法则 选出一个增量  gap就是增量
        for (int gap = n / 2; gap > 0; gap /= 2) {
            for (int i = 0; i < gap; i++) {//创建变量 i 并且循环是小于增量的时候进行自增
//                j = i+ gap就是一次循环的时候的位置  开始是以第二个位置开始 用的插入排序的法则,假设左边的都是有顺序的
                for (int j = i + gap; j < n; j += gap) {//外循环一次 内部循环一圈
//                    j-gap 当前下标减去增量的左边的数
//                    采用插入排序 假设左边的都是有序的 那么当当前位置的数小于增量左边第一个的数  那么就进入循环
                    if (a[j] < a[j - gap]) {
//                        将当前位置的数 存进临时变量
                        int temp = a[j];
//                        k是当前下标相对应的增量左边的那个数
                        int k = j - gap;
//                        当前下标相对应的增量左边的那个数的下标不为负数,并且它大于当前下标的数  进入循环
                        while (k >= 0 && a[k] > temp) {
//                            交换位置
                            a[k + gap] = a[k];
                            k = k - gap;
                        }
//                        交换位置
                        a[k + gap] = temp;
                    }
                }
            }
        }
        System.out.println(Arrays.toString(a));
    }

输出
在这里插入图片描述
可以看出第二个代码 采用的是插入排序算法实现的,所以有的面试官会问希尔排序和插入排序的关系,从上面的第二个代码就可以发现,希尔排序是基于插入排序实现的

总结

  • 希尔排序将增量应用带插入排序,然后逐渐减少增量
  • n-增量排序表示每隔n个元素进行排序
  • 每次在一个数组中采用增量获取出来的新的数组都是采用的插入排序来排出新的信泽数组的
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值