1. 程式人生 > >排序演算法之希爾排序-優化後的插入排序

排序演算法之希爾排序-優化後的插入排序

希爾排序的思想:將待排序的序列分成若干個子序列(由某一分量相隔的元素組成),分別對若干個子序列進行直接插入排序,之後依次縮小分量直到整個序列基本有序,再對整個序列進行直接插入排序,基於插入排序在基本有序的序列中效率極高,因此可以提高直接插入排序的效率。

建議看希爾排序前,先看明白直接插入排序!!!

關於希爾排序的各項資訊:

  • 空間複雜度:O(1)
  • 時間複雜度:由於希爾排序的時間複雜度依賴於增量序列的函式,這是一個數學上尚未解決的問題,因此它的時間複雜度分析比較難,當n(序列長度)在某個特定範圍時,希爾排序的時間複雜度約為O(n^1.3),最壞的時間複雜度是O(n^2)
  • 穩定性:相同的關鍵字記錄可能會劃分到不同的子序列中,可能會改變他們的相對次序,因此不穩定

舉例如下:
當前有一個十個數的無序序列{49, 38, 65, 97, 26, 13, 27, 50, 55, 4}
我們將上文提到的分量命名為gap

  1. 第一次 gap=10/2=5,即從頭到尾將相距gap個位置的元素放入同一個子序列中:{49,13},{38,27},{65,50},{97,55},{26,4}
    對各個子序列進行直接插入排序得到:
    {13,27,50,55,4,49,38,65,97,26}
  2. 第二次 gap=5/2=2,得到子序列:
    {13,50,4,38,97},{27,55,49,65,26}
    對子序列進行插入排序:
    {4,26,13,27,38,49,50,55,97,65}

  3. 第三次gap=2/2=1,得到子序列:
    {4,26,13,27,38,49,50,55,97,65}
    對子序列進行插入排序:
    {4,13,26,37,38,49,50,55,65,97}
    gap等於1並插入排序後,整個排序過程結束,得到有序序列

程式碼如下:

    //希爾排序,先對陣列進行分段直接插入排序,之後再對整個較為有序的陣列進行排序
    public void shellSort1(int[] a, int n) {

        for(int gap=n/2; gap > 0; gap/=2) {

            for(int i=gap; i<n; i++) {

                if
(a[i] < a[i-gap]) { int temp = a[i]; int j; for(j=i-gap; j>=0 && a[j]>temp; j-=gap) { a[j+gap] = a[j]; } a[j+gap] = temp; } } } System.out.println(Arrays.toString(a)); }

測試程式碼如下:

public static void main(String[] args) {
        int[] a = new int[]{2,5,1,3,6};
        ShellSort ss = new ShellSort();

        ss.shellSort1(a, a.length);
    }

測試結果:

[1, 2, 3, 5, 6]