排序7:希尔排序

希尔排序也成缩小增量排序,原理是将待排序列划分为若干组,每组都是不连续的,有 间隔step,step可以自己定,但间隔step最后的值一定是1,也就说最后一步是前后两 两比较。间隔为step的默认划分为一组,先在每一组内进行排序,以使整个序列基本有 序,然后再减小间隔step的值,重新分组再排序......不断重复,直到间隔step小于1则停 止。还是先看代码

public static void shellSort1(int[] array) {
        int length = array.length;
        int step = length >> 1;
        while (step >= 1) {
            for (int i = step; i < length; i++) {
                for (int j = i; j >= step; j -= step) {
                    if (array[j] < array[j - step]) {
                        swap(array, j, j - step);
                    } else {
                        break;
                    }
                }
            }
            step >>= 1;
        }
}

这个过程,我们还是通过图来说明一下吧

上面的排序与冒泡很像,只不过冒泡排序是每次都是间隔为1相邻的两个之间进行比较,而希尔是间隔为step,我们再看另外一种写法:

public static void shellSort2(int[] array) {
        int j;
        int len = array.length;
        for (int step = len >> 1; step > 0; step >>= 1) {
            for (int i = step; i < len; i++) {
                int temp = array[i];
                for (j = i; j >= step && temp < array[j - step]; j -= step) {
                    array[j] = array[j - step];
                }
                array[j] = temp;
            }
        }
 }

首先它是把待比较的变量保存到temp中,然后往前找,如果前面的比他大,就会把前面 的值挪到当前位置,然后再往前找,如果还比当前大那么还挪,直到循环完为止,然后 再把当前保存的temp值放到最前面挪动的那个值。这个挪动和前面介绍的插入排序的挪 动有点类似,只不过插入排序的挪动是一个个往前比较(二分法插入例外),而这个挪 动是每间隔step进行比较然后确定是否挪动。我们上面使用的间隔是数组长度的一半, 这个间隔实际上是可以自己定的,但一定要保证间隔最后的一步是1即可,希尔排序中 大家都比较认可的一种计算间隔的公式是step = step * 3 + 1;我们再来看一下代码:

public static void shellSort3(int[] array) {
         int step=1;
         while (step<=array.length/3){
             step=step*3+1;
         }
         while (step>0){
             for(int i=step;i<array.length;i+=step){
                 if(array[i]<array[i-step]){
                     int tmp=array[i];
                     int j=i-step;
                     while (j>=0 && array[j]>tmp){
                         array[j+step]=array[j];
                         j-=step;
                     }
                     array[j+step]=tmp;
                 }
             }
             step=(step-1)/3;
         }
 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

纵横千里,捭阖四方

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

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

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

打赏作者

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

抵扣说明:

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

余额充值