1. 程式人生 > >數據結構(七)排序---希爾排序

數據結構(七)排序---希爾排序

incr 最好的 直接插入排序 增量 www ref 必須 初始 html

圖解排序算法(二)之希爾排序

定義

希爾排序是希爾(Donald Shell)於1959年提出的一種排序算法。希爾排序也是一種插入排序,它是簡單插入排序經過改進之後的一個更高效的版本,也稱為縮小增量排序,同時該算法是沖破O(n2)的第一批算法之一。
希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。
基本有序:小的關鍵字基本在前面,大的基本在後面,不大不小的基本在中間

基本思想

簡單插入排序很循規蹈矩,不管數組分布是怎麽樣的,依然一步一步的對元素進行比較,移動,插入,比如[5
,4,3,2,1,0]這種倒序序列,數組末端的0要回到首位置很是費勁,比較和移動元素均需n-1次。
而希爾排序在數組中采用跳躍式分組的策略,通過某個增量將數組元素劃分為若幹組,然後分組進行插入排序,隨後逐步縮小增量,繼續按組進行插入排序操作,直至增量為1。
希爾排序通過這種策略使得整個數組在初始階段達到從宏觀上看基本有序,小的基本在前,大的基本在後。
然後縮小增量,到增量為1時,其實多數情況下只需微調即可,不會涉及過多的數據移動。

圖解算法

我們來看下希爾排序的基本步驟,在此我們選擇增量gap=length/2,縮小增量繼續以gap = gap/2的方式,這種增量選擇我們可以用一個序列來表示,{n/2,(n/2
)/2...1},稱為增量序列。
希爾排序的增量序列的選擇與證明是個數學難題,我們選擇的這個增量序列是比較常用的,也是希爾建議的增量,稱為希爾增量,但其實這個增量序列不是最優的。
此處我們做示例使用希爾增量。

技術分享圖片

代碼實現

void ShellSort(SqList *L)
{
    int i, j;
    int increment = L->length;
    do 
    {
        increment = increment / 3 + 1;    //雖然使用/2是一種好理解的方式,但是不是一個效率最好的增量,這裏選擇/3+1
        //我們選擇直接插入的方式進行處理
        
//下面的思路我們全部按照/2來想,我們只需要修改上面的增量即可 for (i = increment + 1; i <= L->length;i++) { if (L->r[i]<L->r[i-increment]) { //需要將L->[i]插入有序增量子表中 L->r[0] = L->r[i]; for (j = i - increment; j>0 && L->r[j] > L->r[0]; j -= increment) L->r[j + increment] = L->r[j]; L->r[j + increment] = L->r[0]; } } } while (increment>1); }

技術分享圖片

性能分析

時間復雜度為O(n^(3/2)),好過O(n^2)
註意:最後一個增量必須為1才行。由於記錄是跳躍式移動,所以不是一種穩定的排序算法

數據結構(七)排序---希爾排序