希尔排序

是从插入排序来的,对于插入排序,当待排记录数很小时,直接插入排序的效率较高;当待排序列按关键字基本有序时直接插入的效率也较高

所以从这两点出发对直接插入排序进行了改进,便产生了希尔排序

该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。


public class shellsort {
    public static void main(String args[]){
        int[] array={34,3,53,2,23,7,14,10};
        shellsort(array);
        for(int a:array)
            System.out.print(a+" ");
    }
    private static void shellsort(int[] nums){
        int len=nums.length;
        if(len<2)   return;
        int gap=len/2;
        while(gap!=0){
            for(int i=0;i<gap;++i){  
                for(int j=i+gap;j<len;j+=gap){
                    if(nums[j]<nums[j-gap]){
                        int temp=nums[j];
                        int k=j-gap;
                        while(k>=0 && nums[k]>temp){
                            nums[k+gap]=nums[k];
                            k-=gap;
                        }
                        nums[k+gap]=temp;
                    }
                }
            }
           gap/=2;
        }
    }

}

一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i += step_size而不是i++)。

例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10

然后我们对每列进行排序:

10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45

將上述四行數字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:

10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45

排序之后变为:

10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94

最后以1步长进行排序(此时就是简单的插入排序了)。

public class shellsort {
    public static void main(String args[]){
        int[] array={34,3,53,2,23,7,14,10};
        shellsort(array);
        for(int a:array)
            System.out.print(a+" ");
    }
    private static void shellsort(int[] arr) {
        int gap = 1, i, j, len = arr.length;
        int temp;
        while (gap < len / 2)
            gap = gap * 2 + 1; // <O(n^(3/2)) by Knuth,1973>: 1, 4, 13, 40, 121, ...
        for (; gap > 0; gap /= 2)
            for (i = gap; i < len; i++) {
                temp = arr[i];
                for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)
                    arr[j + gap] = arr[j];
                arr[j + gap] = temp;
            }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值