1. 程式人生 > 實用技巧 >希爾排序

希爾排序

演算法:

希爾排序的思想是使陣列中任意間隔為h的元素都是有序的。這樣的陣列被稱為h有序陣列。換句話說,一個h有序陣列就是h個互相獨立的有序陣列編織在一起組成的一個數組。在進行排序時,如果h很大,我們就能將元素移動到很遠的地方,為實現更小的h有序創造方便。用這種方式,對於任意以1結尾的h序列,我們都能夠將陣列排序。這就是希爾排序。

實現希爾排序的一種方法是對於每個h,用插入排序將h個子陣列獨立地排序。但因為子陣列是相互獨立的,一個更簡單的方法是在h-子陣列中將每個元素交換到比它大的元素之前去(將比它大的元素向右移動一格)。只需要在插入排序的程式碼中將移動元素的距離由1改為h即可。這樣,希爾排序的實現就轉化為了一個類似於插入排序但使用不同增量的過程。

複雜度:

使用遞增序列1,4,13,40,121,364……的希爾排序所需的比較次數不會超出N的的若干倍乘以遞增序列的長度

程式碼:

public class Shell {

    public static void sort(Comparable[]a){
        int N = a.length;
        int h=1;
        while(h<N/3){
            h = 3*h+1; //1,4,13,40,121,364
        }
        while(h>=1){
            
for(int i = h; i < N; i++){ for(int j =i;j>=h&&less(a[j],a[j-h]);j-=h){ exch(a,j,j-h); } } h = h/3; } } private static boolean less(Comparable v,Comparable w){ return v.compareTo(w)<0; }
private static void exch(Comparable[]a, int i, int j){ Comparable t = a[i]; a[i] = a[j]; a[j] = t; } private static void show(Comparable[] a) { for (int i = 0;i<a.length;i++){ System.out.println(a[i]+" "); } } private static boolean isSorted(Comparable []a){ for (int i =1 ;i <a.length;i++){ if(less(a[i],a[i-1])) return false; } return true; } public static void main(String [] args){ Integer a[] ={1,5,3,2,6,8}; sort(a); assert isSorted(a); show(a); } }

參考資料:

《演算法》-Sedgewick