希爾排序(及其與直接插入排序的區別)


希爾排序基本思想
  基本思想:
     先取一個小於n的整數d1作為第一個增量,把文件的全部記錄分成d1個組。所有距離為dl的倍數的記錄放在同一個組中。先在各組內進行直接插人排序;然后,取第二個增量d2<d1重復上述的分組和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有記錄放在同一組中進行直接插入排序為止。
     該方法實質上是一種分組插入方法。

Shell排序的算法實現

 1 void ShellSort(ElemType A,int n)
 2 {
 3     int i,j,dk;
 4     for(dk=n/2;dk>=1;dk=dk/2)//控制步長變化,每次步長縮小為原來的1/2,直到1
 5     {
 6         for(i=dk+1;i<n;i++)//前dk個默認為dk組的已序
 7         {
 8             if(A[i].key<A[i-dk].key)
 9             {
10                 A[0]=A[i];//暫存A[i],這里不是監視哨;
11                 for(j=i-dk;j>0&&A[0].key<A[j].key;j-=dk)//選尋找插入點
12                     A[j+dk]=A[j];//記錄后移
13                 A[j]=A[0];
14             }
15         }
16     }
17 }

與直接插入排序比較,希爾排序的改進如下:

1、增加了一個for語句,用於控制步長變化。

2、不設置監視哨,故在尋找插入點的for語句中增加j>0來防止訪問越界。

其實,假如去掉這些改進,我們去掉外層的for,然后把dk替換成1,是否發現算法變成了沒有設監視哨的直接插入排序?

 1 void InsertSort(SeqList R,int n)
 2 {
 3     int i,j;
 4     for(i=2;i<=n;i++)
 5     {
 6         if(R[i].key<R[i-1].key)
 7         {
 8             R[0]=R[i];
 9             for(j=i-1;R[0].key<R[j].key;--j)
10                 R[j+1]=R[j];
11         }
12     }
13     R[j]=R[0];
14 }
看看直接插入排序

 

 

性能分析:

1、空間復雜度O(1)。

2、時間復雜度:由於希爾排序的時間復雜度依賴於增量序列的函數。當n在某個特定的范圍時,希爾的時間復雜度約為O(n^1.3),最壞的情況下希爾排序的時間復雜度為O(n^2);

到目前為止,尚未得出一個最好的增量方法序列,希爾提出的方法是d[1]=n/2,d[t]=d[t-1]/2,其中,增量取整數。

穩定性:不穩定

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM