天天看點

希爾排序

希爾排序(Shell Sort)是插入排序的一種,它是針對直接插入排序算法的改進。

希爾排序又稱縮小增量排序,因 DL.Shell 于 1959 年提出而得名。

它通過比較相距一定間隔的元素來進行,各趟比較所用的距離随着算法的進行而減小,直到隻比較相鄰元素的最後一趟排序為止。

希爾排序時間複雜度是 O(n^(1.3-2)),空間複雜度為常數階 O(1)。希爾排序沒有時間複雜度為 O(n(logn)) 的快速排序算法快 ,是以對中等大小規模表現良好,但對規模非常大的資料排序不是最優選擇,總之比一般 O(n^2 ) 複雜度的算法快得多。

希爾排序目的為了加快速度改進了插入排序,交換不相鄰的元素對數組的局部進行排序,并最終用插入排序将局部有序的數組排序。

在此我們選擇增量 gap=length/2,縮小增量以 gap = gap/2 的方式,用序列 {n/2,(n/2)/2...1} 來表示。

如圖示例:

(1)初始增量第一趟 gap = length/2 = 4

希爾排序

(2)第二趟,增量縮小為 2

希爾排序

(3)第三趟,增量縮小為 1,得到最終排序結果

希爾排序

源碼包下載下傳:Download

最内層循環其實就是插入排序:

public class ShellSort {

    //核心代碼---開始

    public static void sort(Comparable[] arr) {

        int j;

        for (int gap = arr.length / 2; gap >  0; gap /= 2) {

            for (int i = gap; i < arr.length; i++) {

                Comparable tmp = arr[i];

                for (j = i; j >= gap && tmp.compareTo(arr[j - gap]) < 0; j -= gap) {

                    arr[j] = arr[j - gap];

                }

                arr[j] = tmp;

            }

        }

    }

    //核心代碼---結束

    public static void main(String[] args) {

        int N = 2000;

        Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 10);

        ShellSort.sort(arr);

        for( int i = 0 ; i < arr.length ; i ++ ){

            System.out.print(arr[i]);

            System.out.print(' ');

}