希爾排序 轉載

希爾排序是對插入排序的一種改進算法,是一種分組插入排序,又稱爲縮小增量排序法。算法

希爾排序的時間複雜度與增量(即,步長gap)的選取有關。例如,當增量爲1時,希爾排序退化成了直接插入排序,此時的時間複雜度爲O(N²),而Hibbard增量(N/2)的希爾排序的時間複雜度爲O(N3/2)。數組

 

(1)、主要步驟:spa

  1. 對一個數組長度爲N的數組,取一個小於N的整數gap(gap稱爲步長)
  2. 根據該步長將數組分爲若干個子數組,全部距離爲gap的倍數的記錄放在同一個子數組
  3. 對每一個子數組進行插入排序
  4. 而後縮減gap的值,並重覆上面的分組和排序
  5. 當gap==1時,整個數組就是有序的
 
(2)、演示過程:

下面以數列{80,30,60,40,20,10,50,70}爲例,演示它的希爾排序過程。3d

 

第1趟:(gap=4)code

 

當gap=4時,意味着將數列分爲4個組: {80,20},{30,10},{60,50},{40,70}。 對應數列: {80,30,60,40,20,10,50,70}
對這4個組分別進行排序,排序結果: {20,80},{10,30},{50,60},{40,70}。 對應數列: {20,10,50,40,80,30,60,70}blog

第2趟:(gap=2)排序

 

當gap=2時,意味着將數列分爲2個組:{20,50,80,60}, {10,40,30,70}。 對應數列: {20,10,50,40,80,30,60,70}
注意:{20,50,80,60}實際上有兩個有序的數列{20,80}和{50,60}組成。
          {10,40,30,70}實際上有兩個有序的數列{10,30}和{40,70}組成。
對這2個組分別進行排序,排序結果:{20,50,60,80}, {10,30,40,70}。 對應數列: {20,10,50,30,60,40,80,70}class

第3趟:(gap=1)im

 

當gap=1時,意味着將數列分爲1個組:{20,10,50,30,60,40,80,70}
注意:{20,10,50,30,60,40,80,70}實際上有兩個有序的數列{20,50,60,80}和{10,30,40,70}組成。
對這1個組分別進行排序,排序結果:{10,20,30,40,50,60,70,80}數據

public void sort(int[] arr) {  
    // gap爲步長,每次減爲原來的一半。  
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {  
        // 共gap個組,對每一組都執行直接插入排序  
        for (int i = 0; i < gap; i++) {  
            group_sort(arr, arr.length, i, gap);  
        }  
    }  
}  
  
private void group_sort(int arr[], int n, int i, int gap) {  
    for (int j = i + gap; j < n; j += gap) {  
        // 若是a[j] < a[j-gap],則尋找a[j]位置,並將後面數據的位置都後移。  
        if (arr[j] < arr[j - gap]) {  
            int tmp = arr[j];  
            int k = j - gap;  
            while (k >= 0 && arr[k] > tmp) {  
                arr[k + gap] = arr[k];  
                k -= gap;  
            }  
            arr[k + gap] = tmp;  
        }  
    }  
}  
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息