排序與搜索——希爾排序

希爾排序

希爾排序(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)定

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容