希尔排序实现

本文深入解析希尔排序算法,介绍其工作原理,即通过设定增量k,对数组进行分组排序,逐步缩小增量直至全排序,提升排序效率。文章通过具体实例展示希尔排序过程,并提供Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

希尔排序

希尔排序:确定一个增量k,每间隔k取一个数值,对这个序列进行快速排序,不断缩小k的值,进行相同操作,直到k的值1的时候,对整个数组进行一次全排序,这个时候整个数组是有序的。增量的取值可能会极大的影响排序的性能,一般选取N/2作为k的值,但这不一定是最佳值。

举个例子

有一个数组: 3 2 6 8 1

第一次增量设置为2:

先对 3 6 1 排序:1 3 6

再对 2 8 排序: 2 8

整合:1 2 3 8 6

第二次增量为1:

增量为1时对整体排序:1 2 3 6 8

代码实现

public class ShellSort {
    /**
     * 希尔排序:通过一个合适的增量来对一个长度为N的数组进行排序,当增量为1时,才对整个数组进行排序,每次小规模排序采用的是插入排序
     * 进行排序时选择一个合理的希尔增量会对程序性能产生较大的影响,通常我们选择N/2作为增量
     */
    //initIncr为初始增量
    public static int[] shellSort(int[] arr, int initIncr) {
        int len = arr.length;
        while (initIncr >= 1) {
            //增量大小取决于这一次需要进行多少次排序
            for (int k = 0; k < initIncr; k++) {
                for (int i = k; i < len; i += initIncr) {
                    //将当前元素存起来
                    int current = arr[i];
                    //从当前元素的前一个开始元素开始比较并移动
                    int j = i - initIncr;
                    while (j >= 0 && arr[j] > current) {
                        arr[j + initIncr] = arr[j];
                        j -= initIncr;
                    }
                    //由于前面j-initIncr导致此处应该用j+initIncr
                    arr[j + initIncr] = current;
                }
            }
            initIncr /= 2;
        }
        return arr;
    }

    public static void main(String[] args) {
        Random r = new Random();
        int[] arr = new int[20];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = r.nextInt(100);
        }
        //未排序
        System.out.printf("排序前:%s \n", Arrays.stream(arr).boxed().map(Object::toString).collect(Collectors.joining(" ")));
        //排好序
        System.out.printf("排序后:%s \n", Arrays.stream(shellSort(arr, 4)).boxed().map(Object::toString).collect(Collectors.joining(" ")));
    }
}

运行结果

排序前:14 47 56 97 5 40 39 33 39 72 91 63 51 81 96 34 3 20 63 7 
排序后:3 5 7 14 20 33 34 39 39 40 47 51 56 63 63 72 81 91 96 97 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值