Java 希尔排序

希尔排序示意图:

希尔排序,说实话有点难,不过还是弄出来了,代码:

package com.vgbh;

public class ShellSorting {

    private static int n = 10 ;//数组长度
    private static int[] arr = new int[n] ;//数组

    static PublicOut pc = null ;//定义外部对象
    static ShellSorting ss = null ;//定义内部对象

    public static void main(String[] args) {
        pc = new PublicOut();
        ss = new ShellSorting();

        ss.data(arr,n);//创建数据
        System.out.println("希尔排序前:");
        pc.prin(arr, n);//打印数据
        ss.shell(arr,n);//希尔排序
        System.out.println("希尔排序后:");
        pc.prin(arr, n);//打印数据

    }

    /*
     * 希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,
     * 而是相隔特定的增量的子序列,对各个子序列进行插入排序;
     * 然后再选择一个更小的增量,再将数组分割为多个子序列进行排序......最后选择增量为1,
     * 即使用直接插入排序,使最终数组成为有序。
     * 
     * 增量的选择:选用Knuth间隔序列
     */

    //希尔排序
    public void shell (int[] arr,int n) {
        int inner , outer ;
        int temp ;

        int h = 1 ;
        while (h < n) h = h*3 + 1;//(Knuth间隔序列:1,4,13,40,121,...)

        //System.out.println("\nstart shell sorting:");

        while (h > 0) {
            //System.out.println("\n\n\n当前的h值为:" + h);

            for (outer=h;outer<n;outer++) {
                //System.out.println("\n第" + outer + "次循环。");
                temp = arr[outer];
                inner = outer ;

                //System.out.println("--------temp:" + temp + "---------inner:" + inner);

                while (inner>h-1 && arr[inner-h]>=temp) {
                    arr[inner] = arr[inner-h];
                    inner -= h;

                    //System.out.println("     arr[inner] :" + arr[inner] + "       inner:" + inner);
                }
                arr[inner] = temp;

                //System.out.println("++++++arr[inner]:" + arr[inner]);
            }
            h = (h-1) / 3;

            //pc.prin(arr, n);
        }

        //System.out.println("end shell sorting:\n");
    }

    public void data (int[] arr,int n) {//排序的数据
        for (int i=0;i<n;i++) {
            arr[i] = 10 - i;//按照一定顺序产生数据:10~0
            //arr[i] = (int)(Math.random()*10);//随机产生数据:0~10随机
        }
    }
}

1.上边提到的Knuth间隔序列,可以去google搜索一下,那对于哈希排序你会理解一半了。

2.中间有许多测试代码,请自动忽略,下面是一段我自己测试的结果,相信会对你有帮助。

/*    
此为数据为{10,9,8,7,6,5,4,3,2,1}时的排序结果,可按照程序的运行结果理解程序的步骤。

希尔排序前:
  10  9  8  7  6  5  4  3  2  1
  ---------------

start shell sorting:

当前的h值为:13

  10  9  8  7  6  5  4  3  2  1
  ---------------


当前的h值为:4

第4次循环。
--------temp:6---------inner:4
     arr[inner] :10       inner:0
++++++arr[inner]:6

第5次循环。
--------temp:5---------inner:5
     arr[inner] :9       inner:1
++++++arr[inner]:5

第6次循环。
--------temp:4---------inner:6
     arr[inner] :8       inner:2
++++++arr[inner]:4

第7次循环。
--------temp:3---------inner:7
     arr[inner] :7       inner:3
++++++arr[inner]:3

第8次循环。
--------temp:2---------inner:8
     arr[inner] :10       inner:4
     arr[inner] :6       inner:0
++++++arr[inner]:2

第9次循环。
--------temp:1---------inner:9
     arr[inner] :9       inner:5
     arr[inner] :5       inner:1
++++++arr[inner]:1

  2  1  4  3  6  5  8  7  10  9
  ---------------


当前的h值为:1

第1次循环。
--------temp:1---------inner:1
     arr[inner] :2       inner:0
++++++arr[inner]:1

第2次循环。
--------temp:4---------inner:2
++++++arr[inner]:4

第3次循环。
--------temp:3---------inner:3
     arr[inner] :4       inner:2
++++++arr[inner]:3

第4次循环。
--------temp:6---------inner:4
++++++arr[inner]:6

第5次循环。
--------temp:5---------inner:5
     arr[inner] :6       inner:4
++++++arr[inner]:5

第6次循环。
--------temp:8---------inner:6
++++++arr[inner]:8

第7次循环。
--------temp:7---------inner:7
     arr[inner] :8       inner:6
++++++arr[inner]:7

第8次循环。
--------temp:10---------inner:8
++++++arr[inner]:10

第9次循环。
--------temp:9---------inner:9
     arr[inner] :10       inner:8
++++++arr[inner]:9

  1  2  3  4  5  6  7  8  9  10
  ---------------


end shell sorting:

希尔排序后:
  1  2  3  4  5  6  7  8  9  10
  ---------------

     */

3.对于希尔排序,我还是建议动手在纸上演算,其实会出现很多错误,但也会更深刻的理解希尔排序,动手丰衣足食。

有问题的可以联系我的邮箱。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vgbh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值