5.希尔排序

5.希尔排序


前言

希尔排序也称为缩小增量排序,是插入排序算法的一种改进版。

希尔排序应该是最难的排序了

希尔排序的诞生是由于插入排序在处理大规模数组的时候会遇到需要移动太多元素的问题。


实现思路

希尔排序的思想是将一个大的数组“分而治之”,将一个大的数组划分为若干个小的数组。以 gap (间隔)来划分,比如数组 [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ,如果以间隔 gap = 2划分,可以划分为 [ 1 , 3 , 5 , 7 ] 和 [ 2 , 4 , 6 , 8 ] 两个数组;对应的,若间隔 gap = 3 ,则划分的数组为: [ 1 , 4 , 7 ] 、 [ 2, 5 , 8 ] 、 [ 3 , 6 ] 。然后分别对这些子数组进行正统的插入排序,排序好后将数组回收到大数组里,再减少间隔 gap 的值重复进行之前的操作,直到间隔 gap = 1时,此时子数组只有一个,就是整个大数组,此时其实都快排好序了,在对这唯一的子数组进行最后一次插入排序的时候,移动的数会很少很少,从而解决了插入排序在处理大规模数组时较多移动次数的问题。


模拟走位

初始数组:[ 26 , 19 , 7 , 37 , 27 , 57 , 67 , 99 , 87 , 17 ]

第一次:

初次计算间隔 gap = 10 / 2 = 5

( 26 走五步是57,以此类推 )

26 19 7 37 27
57 67 99 87 17

进行列排序( 比如,26和57是一列,以此类推 )

26 19 7 37 17
57 67 99 87 27

按行取回放入大数组里:[ 26 , 19 , 7 , 37 , 17 , 57 , 67 , 99 , 87, 27 ]

第二次:

gap = 5 / 2 = 2

( 26 走两步是7,以此类推 )

26 19
7 37
17 57
67 99
87 27

进行列排序( 比如,26、7、17、67、87 是一列,以此类推 )

7 19
17 27
26 37
67 57
87 99

按行取回放入大数组里:[ 7 , 19 , 17 , 27 , 26 , 37 , 67 , 57 , 87 , 99 ]

第三次:

gap = 2 / 2 = 1

( 7 开始一步一步走 )

7
19
17
27
26
37
67
57
87
99

进行列排序

7
17
19
26
27
37
57
67
87
99

按行取回放入大数组里:[ 7 , 17 , 19 , 26 , 27 , 37 , 57 , 67 , 87 , 99 ]

总结:其实很有节奏和规律,不算复杂。


实现代码

    public <T extends Comparable<T>> void shellSorting(T[] array) {
        int len = array.length;
        int i, j, gap;
        // 逐渐减小步长
        for (gap = len / 2; gap > 0; gap /= 2) {
            // 布置行数据
            for (i = 0; i < gap; i++) {
                // 布置列数据
                for (j = gap; j < len; j += gap) {
                    if (array[j - gap + i].compareTo(array[j + i]) > 0) {
                        T temp = array[j - gap + i];
                        array[j - gap + i] = array[j + i];
                        array[j + i] = temp;
                    }
                }
            }
        }
    }

运行

    public static void main(String args[]) {
        Integer[] object = {26, 19, 7, 37, 27, 57, 67, 99, 87, 17};
        System.out.println("\n希尔排序\n");
        ShellSort shellSorting = new ShellSort();
        shellSorting.shellSorting(object);
        System.out.println("\n希尔排序\n");
        for (int i : object) {
            System.out.print(i + " ");
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值