希爾排序
希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進版本。希爾排序是非穩(wěn)定排序算法。該方法因DL.Shell于1959年提出而得名。 希爾排序是把記錄按下標(biāo)的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關(guān)鍵詞越來越多,當(dāng)增量減至1時,整個文件恰被分成一組,算法便終止。
希爾排序過程
希爾排序的基本思想是:將數(shù)組列在一個表中并對列分別進行插入排序,重復(fù)這過程,不過每次用更長的列(步長更長了,列數(shù)更少了)來進行。最后整個表就只有一列了。將數(shù)組轉(zhuǎn)換至表是為了更好地理解這算法,算法本身還是使用數(shù)組進行排序。
例如,假設(shè)有這樣一組數(shù)[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我們以步長為5開始進行排序,我們可以通過將這列表放在有5列的表中來更好地描述算法,這樣他們就應(yīng)該看起來是這樣(豎著的元素是步長組成):
13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10
然后我們對每列進行排序:
10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45
將上述四行數(shù)字,依序接在一起時我們得到:
[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ]
這時10已經(jīng)移至正確位置了,然后再以3為步長進行排序:
10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45
排序之后變?yōu)椋?/p>
10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94
最后以1步長進行排序(此時就是簡單的插入排序了)。
用自己的話過來總結(jié),就是按照間隔排序,是一種變相的插入排序,根據(jù)間隔的不同,劃分不同元素舉例gap=4
希爾排序的分析
代碼實現(xiàn):
def shell_sort(li):
n = len(li)
gap = n//2
while gap >= 1:
for j in range(gap,n):
i = j
while i>0:
if li[i] < li[i-gap]:
li[i],li[i-gap] = li[i-gap],li[i]
i -= gap
else:
break
gap = gap//2
if __name__ == '__main__':
ali = [12,23,11,33,4,55,12,44,52,21]
print(ali)
shell_sort(ali)
print(ali)
分析這個代碼:首先寫的是while循環(huán),這部分就是照搬的插入排序,唯一不同的就是前一個和后一個對比不再是i與i-1,而是間距編程了gap,前一個與后一個的對比編程i與i-gap。
gap就是一個分界線,如果是第三個數(shù)值與第二個比對完之后,還要同第一個比對,所以需要在最后加一個i -= gap,這個與插入排序異曲同工,同時考慮是每個數(shù)值都需要比較,故while的循環(huán)條件為i>0,要實現(xiàn)所有的分組同時比較而不是一個個拆分比較,這就到達了外圈函數(shù)的范圍,就需要一個for循環(huán)來實現(xiàn),即for j in range(gap,n)。
時間復(fù)雜度
最優(yōu)時間復(fù)雜度:根據(jù)步長序列的不同而不同
最壞時間復(fù)雜度:O(n^2)
穩(wěn)定性:不穩(wěn)定