希爾排序，也稱遞減增量排序演算法，是插入排序的一種更高效的改進版本。希爾排序是非穩定排序演算法。 希爾排序是基於插入排序的以下兩點性質而提出改進方法的： 插入排序在對幾乎已經排好序的資料操作時，效率高，即可以達到線性排序的效率 但插入排序一般來說是低效的，因為插入排序每次只能將資料移動一位 歷史 希爾排序按其設計者希爾（Donald Shell）的名字命名，該演算法由 1959 年公佈。一些老版本教科書和參考手冊把該演算法命名為 ShellMetzner，即包含 Marlene Metzner Norton 的名字，但是根據 Metzner 本人的說法，我沒有為這種演算法做任何事，我的名字不應該出現在演算法的名字中。 演算法實現 原始的演算法實現在最壞的情況下需要進行 O n2 的比較和交換。 V Pratt 的書 This was originally presented as the authors PhD thesis Stanford University 1971 對演算法進行了少量修改，可以使得效能提升至 O n log2 n。這比最好的比較演算法的 O n log n 要差一些。 希爾排序透過將比較的全部元素分為幾個區域來提升插入排序的效能。這樣可以讓一個元素可以一次性地朝最終位置前進一大步。然後演算法再取越來越小的步長進行排序，演算法的最後一步就是普通的插入排序，但是到了這步，需排序的資料幾乎是已排好的了（此時插入排序較快）。 假設有一個很小的資料在一個已按升序排好序的陣列的末端。如果用複雜度為 O n2 的排序（氣泡排序或插入排序），可能會進行 n 次的比較和交換才能將該資料移至正確位置。而希爾排序會用較大的步長移動資料，所以小資料只需進行少數比較和交換即可到正確位置。 一個更好理解的希爾排序實現：將陣列列在一個表中並對列排序（用插入排序）。重複這過程，不過每次用更長的 zhhans 列；zhhant 行； 來進行。最後整個表就只有一 zhhans 列；zhhant 行； 了。將陣列轉換至表是為了更好地理解這演算法，演算法本身僅僅對原陣列進行排序（透過增加索引的步長，例如是用 i step_size 而不是 i ）。 例如，假設有這樣一組數 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10，如果我們以步長為 5 開始進行排序，我們可以透過將這列表放在有 5zhhans 列；zhhant 行； 的表中來更好地描述演算法，這樣他們就應該看起來是這樣： 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 然後我們對每 zhhans 列；zhhant 行； 進行排序： 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 將上述四 zhhans 行；zhhant 列； 數字，依序接在一起時我們得到：10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 這時 10 已經移至正確位置了，然後再以 3 為步長進行排序： 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 排序之後變為： 10 14 13 25 23 33 27 25 59 39 65 73 45 94 82 94 最後以 1 步長進行排序（此時就是簡單的插入排序了）。 步長序列 步長的選擇是希爾排序的重要部分。只要最終步長為 1 任何步長序列都可以工作。演算法最開始以一定的步長進行排序。然後會繼續以一定步長進行排序，最終演算法以步長為 1 進行排序。當步長為 1 時，演算法變為普通插入排序，這就保證了資料一定會被排序。 Donald Shell 最初建議步長選擇為 frac n2 並且對步長取半直到步長達到 1。雖然這樣取可以比 mathcal On2 類的演算法（插入排序）更好，但這樣仍然有減少平均時間和最差時間的餘地。 步長序列 最壞情況下複雜度 n2i mathcal On2 2k 1 mathcal On32 2i 3j mathcal Onlog2 n 已知的最好步長序列是由 Sedgewick 提出的 1 5 19 41 109，該序列的項，從第 0 項開始，偶數來自 9 times 4i 9 times 2i 1 和奇數來自 2i2 times 2i2 3 1 這兩個算式 。這項研究也表明 比較在希爾排序中是最主要的操作，而不是交換。 用這樣步長序列的希爾排序比插入排序要快，甚至在小陣列中比快速排序和堆排序還快，但是在涉及大量資料時希爾排序還是比快速排序慢。 另一個在大陣列中表現優異的步長序列是（斐波那契數列除去 0 和 1 將剩餘的數以黃金分割比的兩倍的冪進行運算得到的數列）：1 9 34 182 836 4025 19001 90358 428481 2034035 9651787 45806244 217378076 1031612713 The fibonacci to the power of two times the golden ratio gap sequence 偽程式碼 input an array a of length n with array elements numbered 0 to n 1 inc floor n2 while inc 0 do for i inc n 1 do temp a i j i while j inc and a j inc temp do a j a j inc j j inc a j temp inc floor inc 2 輸入：1 個長度為 n 的矩陣 a，矩陣的編號從 0 到 n 1 整數 inc 從 n 2 到 1，每次迴圈 inc 變為 inc 2 向下取整 i 從 inc 到 n 1，每次迴圈 i 變為 i 1 將 a i 的值賦給 temp j 從 i 到 inc，每次迴圈 j 變為 j inc 如果 a j inc 大於 temp，則將 a j inc 的值賦給 a j 否則跳出 j 迴圈 j 迴圈結束 將 temp 的值賦給 a j i 迴圈結束 inc 迴圈結束 程式程式碼 C 語言 void shell_sort int arr int len int gap i j int temp for gap len 1 gap 0 gap 1 for i gap i len i temp arr i for j i gap j 0 arr j temp j gap arr j gap arr j arr j gap temp C templatetypename T void shell_sort T array int length int h 1 while h length 3 h 3 h 1 while h 1 for int i h i length i for int j i j h array j array j h j h stdswap array j array j h h h 3 Java public static void shellSort int arr int length arrlength int temp for int step length 2 step 1 step 2 for int i step i length i temp arr i int j i step while j 0 arr j temp arr j step arr j j step arr j step temp C public void shellSort int a int h aLength 2 while h1 for int i0ihi for int jihjaLengthjh int tempa j int loc j while loc h itemp a loc h a loc a loc h loc loc h a loc temp h h 2 JavaScript function shell_sort arr for let gap arrlength 1 gap 0 gap 1 for let i gap i arrlength i let temp arr ij for j i gap j 0 arr j temp j gap arr j gap arr j arr j gap temp return arr Python def shell_sort list n len list 初始步長 gap n 2 while gap 0 for i in range gap n 每個步長進行插入排序 temp list i j i 插入排序 while j 0 and jgap 0 and list j gap temp list j list j gap j gap list j temp 得到新的步長 gap gap 2 return list PHP function shell_sort arr php 的陣列視為基本型別，所以必須用傳參考才能修改原陣列 for gap count arr1 gap 0 gap1 for i gap i count arr i temp arr i for j i gap j 0 arr j temp j gap arr j gap arr j arr j gap temp Go package main import fmt func ShellSort array int n len array if n 2 return key n 2 for key 0 for i key i n i j i for j key array j array jkey array j array jkey array jkey array j j j key key key 2 func main array int 55 94 87 1 4 32 11 77 39 42 64 53 70 12 9 fmtPrintln array ShellSort array fmtPrintln array Julia 語言 Julia Sample ShellSort function ShellSort A inc div length A 2 while inc 0 for i in inc1length A j i tmp A i while j inc A j inc tmp A j A jinc j inc end A j tmp end if inc 2 inc 1 else inc floor Int inc 50 11 end end return A end Main Code A 16586131354433 println A Original Array println ShellSort A Shell Sort Array 引用 Category 排序演算法