【數據結構與算法Python實踐系列】5分鐘學會經典排序算法-希爾排序

希爾排序

希爾排序(Shell’s Sort)是插入排序的一種又稱“縮小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一種更高效的改進版本。希爾排序是非穩定排序算法。該方法因D.L.Shell於1959年提出而得名。
希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨着增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。

  • 時間複雜度O(N*logN)
  • 空間複雜度O(1)
  • 不穩定排序:比如一個待排序數組5115,當我們選擇步長爲2開始排序,第一位置上的5和第二個位置上的1交換,得到1155,2個1的順序變換了,破壞了數據的穩定性。

算法原理

希爾排序是改良的插入排序對插入步長進行了調整,插入排序步長爲1,希爾排序的步長是從大到小調整的;首先將要排序數組數按某個增量d分成若干份,每組中記錄的下標相差d,對每組進行插入排序,然後再減小d的取值,再次分組,重複以上過程直至,分成若干組最終以步長爲1的插入排序結束,整個數組的排序完成。

希爾排序算法中即體現了插入排序在有序度高的序列中排序的高效性又綜合了分治法縮小插入排序的數據規模的優勢。

希爾排序中的關鍵是各次迭代所引用的增量,增量序列的步長增長性影響掃描次數,而掃描次數影響邏輯組內元素規模,邏輯組規模及邏輯組有序度影響插入操作次數,因而增量序列的選擇對希爾排序的時間複雜度起決定性影響。

Python實現

示例代碼首次選取數據集長度的一半爲增量序列步長,以後每次減半,直到增量爲1。​

def shell_sort(arr):

    def inster_sort(arr, gap):
        for i in range(gap, len(arr)):
            index = i
            data = arr[i]
            while index > gap and arr[index - 1] > data:
                # 移動基礎 列表,確定要插入的位置
                arr[index] = arr[index - 1]
                index -= 1
            arr[index] = data
        return arr

    # def inster_sort(arr, gap):
    #     for i in range(gap, len(arr)):
    #         index = i
    #         data = arr[i]
    #         while index >= gap and arr[index - gap] > data:
    #             # 移動基礎 列表,確定要插入的位置
    #             arr[index] = arr[index - gap]
    #             index -= gap
    #         arr[index] = data
    #     return arr

    gap = len(arr)

    while gap > 0:
        gap = gap // 2
        inster_sort(arr, gap)
    return arr


if __name__ == "__main__":
    print(shell_sort([45, 32, 8, 33, 12, 22, 19, 97]))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章