1. 程式人生 > >希爾排序(Shell Sort)

希爾排序(Shell Sort)

希爾排序的原理:將待排序資料元素集合按照一定的大小分塊在塊間的資料按照增量(步長)進行直接插入排序,然後根據一定的規則減少步長,再進行一次直接插入排序,直到步長小於1 。

希爾排序需要注意的是最後的增量一定是1 。

下面先給出Java實現程式碼:

public static void shellSort(int array[]) {
        if (null == array || 1 >= array.length)
            return;
        int step = 0, n = array.length, temp, j;
        int len = n;
        do {
            step = (int) Math.sqrt(n);
            for (int i = step; i < len; i++) {
                temp = array[i];
                j = i - step;
                while (j >= 0 && temp < array[j]) {
                    array[j + step] = array[j];
                    j -= step;
                }
                array[j + step] = temp;
            }
            n = step;
        } while (step > 1);
    }
程式碼中初始步長為 Math.sqrt(n), n 為帶排資料的長度,內部迴圈:
for (int i = step; i < len; i++) {
                temp = array[i];
                j = i - step;
                while (j >= 0 && temp < array[j]) {
                    array[j + step] = array[j];
                    j -= step;
                }
                array[j + step] = temp;
            }
是對一個特定的步長做一次直接插入排序,當step == 1 時,該待排序集合基本有序所以不用大量移動元素。
按照上面步驟對下列元素集合做希爾排序的過程如下:

集合R = {37, 40, 38, 42, 461, 5, 7, 9, 12}
第一趟排序取步長 step = 3 ,


途中使用了三種不同的標記,表示了步長中的每一個元素{Ri , Ri+1 , ... Ri+step -1} 。

第二趟排序取步長step = Math.sqrt(3) = 1 ;

得到最後排好序的序列: 5 , 7, 9,12, 37, 38,42,61 。

在上面的例子中比較特殊,之進行了兩趟排序就完成了,而且每趟排序中元素個數都是相同的。而在實際使用中一般step取值為:

step = step/2.2 ;

希爾排序的時間複雜度:O(N^3/2)  到 O(N^7/6) .