1. 程式人生 > >排序演算法之希爾排序 java實現

排序演算法之希爾排序 java實現

知識準備

基礎概念

希爾排序:在直接插入排序的基礎上進行的優化,直接插入排序在n值小的時候效率比較高,在n很大的時候如果待排序序列基本有序,效率依然很高,時間效率可以提升為O(n)。希爾排序也稱之為縮小增量排序。
1.先選取一個小於n的整數d(步長),然後按照步長d將待排序序列分為d組,從第一個記錄開始間隔為d的為一個組。然後對各組內進行直接插入排序,一趟過後,間隔為d的序列有序,隨著有序性的改善,減少步長d重複進行 。直到d=1使得間隔為1的記錄有序,也就達到了整體有序

步驟分解

1.我們有序列 18、 24、 12 、15 、1 、27、 17 、19。我們以步長為序列長度除以2作為第一次的步長。以後每次都在原有的步長基礎上除以2取整。直到步長為1後進行直接插入排序為止。

希爾排序.png
如上圖所示,我們把序列根據步長8/2=4,將序列分成四組分別為:
[1,18]、[24,27]、[12,17]、[15,19]。
然後對各組進行直接插入排序得到最後的結果:

1、24、12、15、18、27、17、19

2.繼續縮減步長,在上一步的結果序列1、24、12、15、18、27、17、19基礎上使得步長為上一步步長除以2,即步長為4/2=2重複第一步如下圖所示。

希爾排序.png
根據步長分為兩組,[1,12,17,18]、[15,19,24,27]然後分別執行直接插入排序獲得結果:

1、15、12、19、17、24、18、27

3.我們已經看到序列逐步成為有序的過程,知道最後步長為1,如當前例項。執行到第三步步長為2/2=1,所以進行最後一步的直接插入排序,序列就是有序序列了。

希爾排序.png
得到最終序列:

1、12、15、17、18、19、24、27

程式碼實現

 /**
     * 希爾排序
     *
     * @param num
     */
    public static void ShellSort(int num[]) {
        int temp;
        //預設步長為陣列長度除以2
        int step = num.length;
        while (true) {
            step = step / 2;
            //確定分組數
            for (int
i = 0; i < step; i++) { //對分組資料進行直接插入排序 for ( int j = i + step; j < num.length; j = j + step) { temp=num[j]; int k; for( k=j-step;k>=0;k=k-step){ if(num[k]>temp){ num[k+step]=num[k]; }else{ break; } } num[k+step]=temp; } } if (step == 1) { break; } } }

注:網路上有些希爾排序寫的稍微有點問題,把希爾排序裡面的直接插入寫成了冒泡了。