Python實現堆排序

  近日對堆排序做了一個簡單的學習,簡單整理如下:

1.堆分爲大根(頂)堆與小根(頂)堆,升序排序採用大根堆,降序排序採用小根堆。

2.堆是完全二叉樹,利用層序遍歷(遍歷方式還有前中後)映射到數組後,假設樹或子樹的根節點爲arr[root],則其對應的子節點分別爲arr[root*2+1],arr[root*2+2]。

3.對於堆排序,基本思想是,將一個無序序列調整爲一個大根堆,就可以找出這個序列的最大值,然後將找出的這個值交換到序列的最後一個,這樣有序序列就元素就增加一個,無序序列元素就減少一個。對新的無序序列重複如上的操作,最終會實現排序。即分爲兩塊:1.大根堆的構建。2.首尾元素互換。排序的過程就是每次待排序的序列長度減去1再執行這兩步。

4.對於代碼的書寫理解,第一次構建大根堆,需要從無序序列的樹的第一個非葉子節點開始,從下至上,從右至左,對每一個節點進行調整,以構造一個大根堆,此時調用big_endian(arr,first,len(arr)-1),first利用for遞減。交換後得到的樹,只有樹的根節點不滿足大根堆的定義,只需要調整即可,此時調用big_endian(arr,0,end-1)。整體代碼是構建大根堆、交換、調整、交換、調整.......

5.代碼如下

'''堆排序'''
'''1.從下至上,從右至左,對每個節點進行調整,以得到一個大頂堆'''
'''2.首尾互換,尾部元素已是有序序列,堆元素個數減1,此部分仍爲無序序列,繼續調整'''

def big_endian(arr,start,end):
    root = start
    while True:
        child = root * 2 + 1
        if child > end:
            break
        if child+1 <= end and arr[child] < arr[child+1]:
            child += 1
        if arr[root] < arr[child]:
            arr[root], arr[child] = arr[child], arr[root]
            root = child
        else:
            break

def heap_sort(arr):
    first=len(arr) // 2 - 1
    for start in range (first, -1, -1):
        big_endian(arr, start, len(arr)-1)
    for end in range (len(arr)-1, 0, -1):
        arr[0], arr[end] = arr[end], arr[0]
        big_endian(arr, 0, end-1)

def main():
    l = [3, 1, 4, 9, 6, 7, 5, 8, 2, 10]
    print (l)
    heap_sort(l)
    print (l)

if __name__ == "__main__":
    main()

轉載:

https://www.jianshu.com/p/48303be6d7eb

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章