排序演算法學習筆記 堆排序的Python實現

2021-10-25 18:56:28 字數 1593 閱讀 1597

網上找了很多堆排序的帖子,大部分**都沒有注釋,自己理解後寫了帶注釋的。

堆排序的原理:

構造大頂堆或小頂堆,使得根節點,即目標陣列arr[0]為最大/最小。交換arr[0]和arr[-1],將最大值/最小值儲存到最後乙個位置,然後以arr[-1]前面的元素構造大頂堆,重複上述過程。

**

# 主要分為三部分

defheap_sort

(s):

# 第一部分,heapify函式,第一次構造大頂堆,需要從最後一排的非葉子節點的最後乙個開始,向上遍歷

# 不能由上向下的原因是,需要將可能的大數字從下面搬運到上面

defheapify

(s,length,i)

: l = i*2+

1 r = i*2+

2 largest = i

if l < length and s[l]

> s[largest]

: largest = l

if r < length and s[r]

> s[largest]

: largest = r

if largest != i:

s[i]

, s[largest]

= s[largest]

,s[i]

heapify(s,length,largest)

# 第二部分,從後向前/從下向上呼叫heapify初始化大頂堆

length =

len(s)

for i in

range

(length//2-

1,-1

,-1)

: heapify(s,length,i)

# 第三部分,大頂堆就緒,從後向前遍歷s,將s[0],即大頂堆根節點和最後的葉子節點對調,並length-=1,使得接下來構造大頂堆時,剛剛對調的最後一位不會被重新排序。並且一定要從上向下構造大頂堆。

for i in

range

(len

(s)-1,

0,-1

):s[0]

,s[i]

= s[i]

,s[0

] length -=

1 heapify(s,length,0)

print

(s)

我自己學習堆排序**時,一直不理解第一次構造大頂堆的時候為什麼要從下向上,而第一次構建完成並將首位元素對調後的構造卻要從下向上。仔細想想後,是因為一開始的陣列是無序的,從上向下的構造會因為當左右節點比根節點小,且比這三個節點更大的節點在更深層節點時,會遍歷不到深層節點,導致大值沒有被從深層節點換到根節點。例如[3,2,1,4],若從上向下遍歷,子樹[3,2,1]滿足條件,則不會再向下遍歷,最大值4沒有被換上來。從下向上遍歷時,[3,2,1,4]–>[3,4,1,2]–>[4,3,1,2],就可構造大頂堆。而之後構造大頂堆時一定要從上向下,因為最小的數字現在在根節點,最大的數字在根節點的子節點上,若從下向上沒辦法把最小的數字搬運到葉子節點。

演算法學習 堆排序

一 關於二叉樹和堆的基本概念 1 二叉樹 每個節點,最多有2個子樹的數結構。左右子樹,也是最多有2個子節點。2 滿二叉樹 除最後一層外,每個節點都有2個子節點。3 完全二叉樹 存在的節點,和滿二叉樹的節點完全對應。4 堆 max heap 最大的元素永遠在根節點 任一非終端節點資料均不小於其左 右孩...

排序演算法學習之堆排序

堆排序 英語 heapsort 是指利用 堆這種資料結構所設計的一種 排序演算法 堆是乙個近似 完全二叉樹 的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。簡單的就是將乙個陣列看作是乙個二叉樹,然後每個父節點跟自己的子節點比較 最大的就成為父節點。如下圖 當第一輪對...

經典演算法學習 堆排序

堆排序是相對其他排序稍微麻煩的排序,是一種利用堆的性質進行的選擇排序。堆其實是一棵完全二叉樹,只要任何乙個非葉節點的關鍵字不大於或者不小於其左右孩子節點,就可以形成堆。堆分為大頂堆和小頂堆。由上述性質可知大頂堆的堆頂的關鍵字是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的。堆排序同快速...