希爾排序是donald shell於2023年提出來的一種排序演算法,它是第一批突破這個時間複雜度的演算法之一。大話資料結構對這個演算法的講解,我看得一知半解的,之後網上找了下資料,發現維基百科對這個演算法的講解非常不錯,特在此整理一波。希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
先上個維基百科的**,不知道你們看不看得懂,反正我不是很懂......
說說我的個人理解:
希爾排序其實就是直接插入排序的公升級,原理就是先將整個待排序列按照某個增量(也稱步長)分割成若干個子串行分別進行直接插入排序,然後合併,之後依次縮小增量大小在進行排序,當增量足夠小(通常為1)時,再對全體元素進行直接插入排序,而此時需排序的資料幾乎是已排好的了,所以此時插入排序較快。
當然如果你覺得文字比較乏味就看下面的這些例子吧
例如,假設有這樣一組數[9 1 5 8 3 7 4 6 2]
,如果我們先以步長為4進行分割,就是這樣:
9 1 5 8
3 7 4 6
2
然後我們對每列進行排序(注意每列哦):
2 1 4 6
3 7 5 8
9
將上述四行數字,依序合併我們得到:[ 2 1 4 6 3 7 5 8 9 ]
。此時2已經往前移,而8,9已經在後兩位,然後再以2為步長進行分割:
2 1
4 63 7
5 89
繼續排序:
2 1
3 64 7
5 89
合併得到[ 2 1 3 6 4 7 5 8 9]
,此時序列已經基本有序,需交換資料的情況大為減少,這時整列進行直接插入排序效率就非常高。
最終完成排序過程,也就是步長為1時,得到最終序列為:1 2 3 4 5 6 7 8 9
。
#include #define maxsize 100 //用於要排序陣列的最大值
(位置為1 5 9),之後在時此時,做出的交換如上圖所示(圖略差...),分為三個步驟:typedef struct //定義乙個順序表結構
sqlist;
void shellsort(sqlist *l)
} int main()
;
sqlist l;
l.length = sizeof(array)/sizeof(array[0]); //獲取陣列長度
for(i=0;i可能有幾個步驟略難懂,這裡解釋下:
當時,9和3進行了一次交換,變為(3 9 2)
步長的選取非常關鍵,但是步長的選擇沒有統一規定,也沒絕對的規律。只要滿足最後乙個步長為1即可.donald shell最初建議步長選擇為,雖然這樣去可以比類的演算法更好,但仍然有減少平均時間和最差時間的餘地維基百科給出的部分步長與最壞情況下複雜度有:
已知的最好步長序列是由塞奇威克提出的(1,5,19,41,109,...),該序列的項來自和這兩個算式。這項研究也表明「比較在希爾排序中是最主要的操作,而不是交換。」用這樣步長序列的希爾排序比插入排序要快,甚至在小陣列中比快速排序和堆排序(後續部落格整理),但是在涉及大量資料時希爾排序還是比快速排序慢。
資料結構 希爾排序!!!
希爾排序是將一組資料進行分組,再將分組的資料進行排序,這樣資料就會逐漸的趨向有序,當分組的個數為1的時候將整個陣列排序一遍,那麼整個陣列就排序好了。基本思想 先將整個待排元素序列分割成若干個子串行 由相隔某個 增量 的元素組成的 分別進行直接插入排序,然後依次縮減增量再進行排序,待整個序列中的元素基...
資料結構 希爾排序
1 希爾排序是在直接插入排序的基礎上改良而來的,直接插入排序需要記錄基本有序的情況下才能變得很高效,希爾排序便是採取跳躍分割的策略,將相距 增量 的元素組成乙個子串行,這樣才能保證最後進行直接插入排序時的序列是基本有序的。希爾排序的時間複雜度是 2 希爾排序實現演算法 include include...
資料結構 希爾排序
希爾排序。終於在此刻將這個排序學完了。這個排序講什麼的呢?就是說,它對乙個序列,取了乙個gap的步長。然後呢,用gap將這個序列分成了很多組,然後就是每組進行插入排序 插入排序 將乙個序列從前往後走,每走一步,就將這個元素和它前面的所有元素比較交換位置。下面上 def shell sort alis...