希爾排序基本思想和算法代碼

先取一個小於n的整數d1作爲第一個增量,把文件的全部記錄分組。所有距離爲d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然後,取第二個增量d2<d1重複上述的分組和排序,直至所取的增量 =1( < …<d2<d1),即所有記錄放在同一組中進行直接插入排序爲止。
該方法實質上是一種分組插入方法
比較相隔較遠距離(稱爲增量)的數,使得數移動時能跨過多個元素,則進行一次比較就可能消除多個元素交換。D.L.shell於1959年在以他名字命名的排序算法中實現了這一思想。算法先將要排序的一組數按某個增量d分成若干組,每組中記錄的下標相差d.對每組中全部元素進行排序,然後再用一個較小的增量對它進行,在每組中再進行排序。當增量減到1時,整個要排序的數被分成一組,排序完成。
一般的初次取序列的一半爲增量,以後每次減半,直到增量爲1。

假設待排序文件有10個記錄,其關鍵字分別是:
592,401,874,141,348,72,911,887,820,283。
增量序列的取值依次爲:
5,2,1

在這裏插入圖片描述
操作步驟:
(1)相隔距離爲gap= 5 的元素組成一組,可以分爲 5 組,按照直接插入排序的方法對每個組進行排序。
(2)再上次的 gap 縮小一半,即 gap= gap / 2 = 2 (取整數)。這樣每相隔距離爲 2 的元素組成一組,可以分爲 2 組,按照直接插入排序的方法對每個組進行排序。
(3)在第三趟排序中,再次把 gap 縮小一半,即gap = gap / 2 = 1。 這樣相隔距離爲 1 的元素組成一組,即只有一組,按照直接插入排序的方法對每個組進行排序。此時,排序已經結束。

算法實現

  public static void shellSort(int a[]) {
 
                            intd= a.length;//gap的值
 
                            while (true){
 
                                   d = d/ 2;//每次都將gap的值減半
 
                                   for (int x = 0; x< d; x++) {//對於gap所分的每一個組
 
                                          for (int i = x+ d; i < a.length; i= i + d) {      //進行插入排序
 
                                                 int temp= a[i];
 
                                                 intj;
 
                                                 for (j= i - d; j>= 0 && a[j] > temp;j = j - d){
                                                        a[j+ d] = a[j];
                                                 }
                                                 a[j+ d] = temp;
                                          }
                                   }
                                   if (d== 1) {//gap==1,跳出循環
                                          break;
                                   }
                            }
       }

最壞情況下時間複雜度:O(N*logN),最壞的情況下和平均情況下差不多。
在排序過程中,需要一個臨時變量存儲要插入的值,所以空間複雜度爲1。
希爾排序中相等數據可能會交換位置,所以希爾排序是不穩定的算法。

發佈了24 篇原創文章 · 獲贊 4 · 訪問量 3323
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章