希尔排序的实现

希尔排序是在直接插入排序的基础上来的,理解了直接插入排序,希尔排序则非常简单:

public class ShellSort {

    public static void main(String[] args) {
        int a[] = {9,8,7,6,5,4,3,2,1,0};
        sortByShell(a,a.length);
        System.out.println(Arrays.toString(a));
    }

    public static void sortByShell(int a[],int high) {
        for (int i = 1; i < a.length; i++) {        //每次开始的地方为 i,从 1 到 末尾
            int temp = a[i];            //要插入的元素
            int j;
            for (j = i; j >= 1 && a[j - 1] > temp; j = j-1) {  //连续的往前探寻(每次-1),找到一个比temp小的元素,插到这个元素后面
                a[j] = a[j - D];                             //若当前元素比temp大则往后稍稍,只往后稍1个位置
            }
            a[j] = temp;          //将元素放到对应的位置
        }
    }
}

希尔排序:

public class ShellSort {

    public static void main(String[] args) {
        int a[] = {9,8,7,6,5,4,3,2,1,0};
        sortByShell(a,a.length);
        System.out.println(Arrays.toString(a));
    }

    public static void sortByShell(int a[],int high) {
        for (int D = high >> 1; D > 0; D = D >> 1) {    //希尔排序,在最外面增加一层循环,使用上增量序列
            for (int i = D; i < a.length; i++) {        //每次开始的地方,由D决定
                int temp = a[i];            //要插入的元素
                int j;
                for (j = i; j >= D && a[j - D] > temp; j = j-D) {  //跳跃的往前探寻(每次-D),找到一个比temp小的元素,插到这个元素后面
                    a[j] = a[j - D];                             //当前元素比temp大则往后稍稍,且往后稍D个位置
                }
                a[j] = temp;          //将元素放到对应的位置
            }
        }
    }
}

可以看出,希尔排序相比于直接插入排序它不是连续的往前探寻合适位置的,而是每次往前探寻D个位置,探寻不成功元素也是往后挪D个单位。D的计算直接影响希尔排序的复杂度,一般D1 = length/2,D2 = D1/2。还有很多增量的计算方法,比较复杂。

希尔排序的复杂度计算也是尚未完成的工作,O(n)最好情况,O(n^2)最坏情况,目前估计平均为 O(n^1.3),空间复杂度O(1)。希尔排序需要知道序列的步长,且在数据量不大时好用,数据量一大还不如快排的性能好(n很大时,n^1.3 > nlogn)

猜你喜欢

转载自www.cnblogs.com/shen-qian/p/12180442.html