希爾排序(shell sort)是插入排序方式的一種,又稱「縮小增量排序」,是直接插入排序演算法的一種更高效的改進版本。
直接插入排序,它的效率在某些時候是很高的,比如,資料集
本身就是基本有序的,只需要少量的插入操作,就可以完成整個資料集
的排序工作,此時直接插入很高效;還有就是資料量比較少時,直接插入的優勢也
比較明顯。可問題在於,這兩個條件本身就過於苛刻,現實中資料量少或者基本有序都屬
於特殊情況。
因此,希爾排序的基本思想就是:將需要排序的序列劃分為若干個較小的序列,對這些序列進行直接插入排序,通過這樣的操作可使需要排序的數列基本有序,最後再使用一次直接插入排序。
怎麼劃分子串行?假設我們現在有乙個序列arr[10] = 。
首先試一下分組劃分子串行:我們將序列分出三組、和,然後排序為、、,再合併成1,5,9,3,7,8,2,4,6},顯然這個序列並不滿足基本有序的條件。
因此使用跳躍法分割子串行:將相距某個『增量'的資料組成乙個子序列。這樣才能保證在子串行內分別進行直接插入排序後得到的結果是基本有序而不是區域性有序。
對於希爾排序而言,增量是重中之重,可究竟應該選擇怎樣的增量才是最好目前還是乙個數學難題,迄今為止還沒有人找到一種最好的增量序列,不過希爾給出乙個n/k的增量序列(簡單常用但不算好),n為序列長度,k的取值範圍一般在2~6之間,當然最好還是根據具體情況進行選擇增量序列。而當k=n時,步長為1,希爾排序就是直接插入排序。
如果看剛開始看不懂希爾排序,就忽略increment的定義和設定,然後把increment=1帶進去看,會發現和直接插入排序一模一樣。
/*希爾排序演算法*/
void shell_sort(int *arr, int len) }}
}
我們先計算增量increment=9/2=4,然後看一下等待排序的序列,根據增量在腦海將序列進行分組:、、、,這將有助於我們理解。
首先進行increment=4的第一次迴圈,i=increment+1=4+1=5,a[i-increment=1]=9 大於 a[i=5]=3,所以要9要後移,3要前移。
這一步相當於直接插入排序在處理序列中的第二個元素3。
繼續進行increment=4的第二次迴圈,a[i-increment=2]=1 小於 a[i=6]=7,所以不需要移動。
這一步相當於直接插入排序在處理序列中的第二個元素7,因為序列只有兩個元素所以這個序列已經排序完畢。
繼續進行increment=4的第三次迴圈,a[i-increment=3]=5 大於 a[i=7]=4,所以5要後移,4要前移。
這一步相當於直接插入排序在處理序列中的第二個元素4,因為序列只有兩個元素所以這個序列已經排序完畢。
繼續進行increment=4的第四次迴圈,a[i-increment=4]=8 大於 a[i=8]=6,所以8要後移,6要前移。
這一步相當於直接插入排序在處理序列中的第二個元素6,因為序列只有兩個元素所以這個序列已經排序完畢。
繼續進行increment=4的第五次迴圈,a[i-increment=5]=9 大於 a[i=9]=2,所以9要後移,2要前移。此時還未結束,2還要繼續前移。
因為這一步相當於直接插入排序在處理序列中的第三個元素2,2還要與3比較並前移,才算這個序列排序完畢。
此時increment=4的的迴圈進行完畢,得到了下圖這樣基本有序的的序列。這就是希爾排序的精華所在,將關鍵字小的資料跳躍式的前移,而不是直接插入排序的一步一步地往前「挪」,所以希爾排序的一輪迴圈等於直接插入排序的很多輪迴圈,減少了大量的比較移動次數。
接著就是increment=4/2=2,開始新一輪的迴圈,重複上述的步驟,這裡不再詳細解釋。
希爾排序的時間複雜度分析是乙個複雜的問題,涉及到一些數學上尚未解決的難題。
所以關於希爾排序的時間複雜度,我只能給出乙個答案:最好情況為o(n^1.3),最壞情況肯定是o(n²),平均情況為o(n㏒n)。
注:希爾排序經常涉及到arr[i-increment]操作,其中increment為希爾排序的當前增量或步長,這種隨機訪問元素的操作不適合鏈式儲存結構,因為每次遍歷都會浪費大量時間,極大降低演算法的效率,不管是單鏈表還是雙向鍊錶。
補充實測:在資料量千萬級,k=2效率最低;k=4效率最高,速度比k=2快1s;k=3、5、6之間相互差0.1s左右,但都比k=2快0.5s。
資料結構與演算法 希爾排序
希爾排序又稱縮小增量排序,實質上是分組直接插入排序。為了方便理解,先不討論如何獲得合適的增量陣列和整個演算法的 1 修改直接插入排序的 實現增量為gap的直接插入排序。將陣列從start到end中間隔為gap的子串行進行直接插入排序 private static void straightinser...
資料結構 演算法 希爾排序
希爾排序過程 希爾排序的基本思想是 將陣列列在乙個表中並對列分別進行插入排序,重複這過程,不過每次用更長的列 步長更長了,列數更少了 來進行。最後整個表就只有一列了。將陣列轉換至表是為了更好地理解這演算法,演算法本身還是使用陣列進行排序。def shell sort alist 希爾排序 n len...
資料結構與演算法(八)希爾排序
希爾排序 1.希爾排序的產生 希爾排序是由科學家donald l.shell提出的,希爾排序基於插入排序,並新增了一些新的特性,從而大大提高插入排序的執行效率。2.插入排序的缺陷,多次移動 參見 插入排序 假如乙個很小的資料在靠右端的位置上。那麼要將該資料排序到正確的位置上,則所有的中間資料都需要向...