JAVA排序算法之希尔排序

本文深入剖析希尔排序算法,通过详细的代码解读帮助理解其工作原理。希尔排序是一种高效的插入排序改进版本,通过将数组按一定增量分组并分别进行排序来提高效率。

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

希尔排序

前言

本章内容对希尔德原理及特点并没有做太多叙述,主要目的是对希尔排序代码进行
详细解释,百度的代码大多没有详解,这里加了许多注释,帮助读者理解代码,从而理
解希尔排序内容
简介
希尔排序是插入排序的一种,也成缩小增量排序,是直接插入排序算法的
一种更高效的改进版本;
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入算法排序,
每组包含的元素越来越多,当增量减至1.整个数组恰被分成一组,
算法便终止
排序过程
缩小增量
希尔排序属于插入类排序,是将整个有序序列分位
若干个小的子序列分别进行插入排序;
排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;
然后取d2<d1,重复上述分组和排序操作;
直至di=1,即所有记录放进一个组中排序为止;
代码实现

    public static void main(String[] args) { 

        int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};   //排序前数组
        int d = a.length;    //用d接收数组长度
        while (true) {       //条件永远为真,不断进行循环,用break跳出循环
            d = d / 2;       //判断分隔多少个数为一组,比如d=6,则下标为0,6,12的分一组,下标为1,7的分一组,2,8为一组
                             //当d=3时,下标为0,3,6,9,12为一组,下标为1,4,7,10为一组,2,5,8,11为一组
                            //当d=1时,0,1,2,3,4,5,6,7,8,9,10,11,12为一组
            for (int i = 0;i < d;i++ ) {      //第一次while循环,d=6时,一共分6组,所有i<6,数组下标从0开始,每组内的第一个元素下标分别为0,1,2,3,4,5,用i表示,进行6次for循环,每次循环将这组内的数据排好序
                                              //第二次while循环时,d = 3,一共分3组,此时i<3,进行三次循环,每组内的第一个元素下标分别为0,1,2,利用for循环,每次循环将这组内的数据排好序
                for(int j = i + d;j < a.length;j = j + d) {  //第一次while循环,共分6组,此次for循环,找到每一组的第二个元素
                                                             //先将j赋值,再判断j与a.length的大小,i+1是这组循环中的第二个元素,之所以先i+1是为了
                                                            //确保进入循环体时,下一个元素存在
                    int temp = a[j];            //用temp保留欲插入元素的值,下面排序时使用直接插入排序,数组元素会后移,将后面一位元素覆盖
                    int k;            //定义一个初始值,便于与其他变量分离开      
                    for(k = j - d;k >= 0 && temp < a[k];k = k - d ) { 
                    //k >= 0 需要在&&符合前面,因为&&符合存在短路现象,k<0时.a[k]下标越界了,需要被短路,从而保证代码正常执行
                    //直接插入排序,将这组内的数据进行比较,(后移覆盖)
                        a[k + d] = a[k];
                    }
                    a[k + d] = temp;   //for循环时,k=k-d,执行完毕后,判断条件不成立,循环结束,但未执行循环体,所以这里要k+d而不是k
                    }

                }
            if(d == 1) {    //d=1时,元素间隔为0,即所有元素分成一组,且已排序完成.故跳出循环
                break;
            }
        }
        System.out.println("排序后:");   //打印已知数组
        for(int i = 0; i < a.length;i++)
        {
            System.out.print(a[i] + "  ");
        }
    }
小结
代码中德变量 i,j,k还是比较绕的,需要耐心理解,本章主要帮助读者理解代码内容
,至于原理,很多网页均有详细说明.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值