希爾排序基本思想
基本思想:
先取一個小於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,其中,增量取整數。
穩定性:不穩定