一、關於二叉樹和堆的基本概念
1、二叉樹
每個節點,最多有2個子樹的數結構。
左右子樹,也是最多有2個子節點。
2、滿二叉樹
除最後一層外,每個節點都有2個子節點。
3、完全二叉樹
存在的節點,和滿二叉樹的節點完全對應。
4、堆:
max heap:最大的元素永遠在根節點
任一非終端節點資料均不小於其左、右孩子節點。
min heap: 最小的元素永遠在根節點
任一非終端節點資料均不大於其左、右孩子節點。
5、堆的特點:
i 表示索引,用公式找到索引所在節點的父節點和左右孩子節點的索引。
parent = (i-1)//2
c1 = 2*i+1
c2 = 2*i+2
二、堆排序的核心思想
以max heap 為例:
第一步:建堆,保證最大元素是堆頂
第二步:把堆頂元素和最後乙個元素位置交換
第三步:調整堆結構,使堆滿足 max heap ,調整的時候不再考慮最後乙個位置元素
第四步:再次將堆頂元素和調整後堆的最後乙個元素位置交換
第五步:調整堆結構
第六步:迴圈
考慮實現過程:
1.如何讓陣列滿足堆的定義:建堆
構建堆的過程:
1)從堆的最後乙個非葉子節點開始,進行調整
對於長度為n的堆,確定最後乙個非葉子節點的位置:n//2-1
調整過程:在最後乙個非葉子節點 的左右子節點中,找到最大的元素,交換位置
2)找到倒數第二個非葉子節點,不滿足max需要調整,滿足則不調整
3)一直找到最後乙個非葉子節點進行調整,最後滿足了max heap的條件
堆頂元素和最後乙個元素,交換。
交換後破壞了原有堆的結構。
然後縮小堆的規模,繼續調整成max heap。
2. 調整完以後,繼續交換
三、**
#調整堆結果
defheapify(arr,action_node_index,length):
'''arr:要傳入的陣列
action_node_index:待調整的堆的節點的索引
length :堆的規模
'''left_child_index = 2*action_node_index+1right_child_index = 2*action_node_index+2max_value_index =action_node_index
#分別和左右子節點比較,找到最大的值對應的index
#在查詢的堆的範圍內
if left_child_indexand arr[left_child_index]>arr[max_value_index]:
max_value_index =left_child_index
if right_child_indexand arr[right_child_index]>arr[max_value_index]:
max_value_index =right_child_index
#如果最大值的索引發生了變化,交換位置
if max_value_index!=action_node_index:
arr[max_value_index],arr[action_node_index]=arr[action_node_index],arr[max_value_index]
#因為位置的交換,可能導致交換後的堆不滿足堆的結構
#繼續調整基於該節點為根的堆結構
heapify(arr,max_value_index,length)
#建堆:從最後乙個非葉子節點
defbuildheapify(arr):
for i in range(len(arr)//2-1,-1,-1):#
左必右開,到0索引結束
heapify(arr,i,len(arr))
#堆排序
defheapifysort(arr):
length =len(arr)
buildheapify(arr)
for i in
range(length):
#做交換
arr[0],arr[length-i-1]=arr[length-i-1],arr[0]
#調整堆
heapify(arr,0,length-1-i)
return
arrarr = [-111,12,0,-6,12,88,34,8,-3]
(heapifysort(arr))#結果
[-111, -6, -3, 0, 8, 12, 12, 34, 88]
2、時間複雜度:o(nlogn)
排序演算法學習之堆排序
堆排序 英語 heapsort 是指利用 堆這種資料結構所設計的一種 排序演算法 堆是乙個近似 完全二叉樹 的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。簡單的就是將乙個陣列看作是乙個二叉樹,然後每個父節點跟自己的子節點比較 最大的就成為父節點。如下圖 當第一輪對...
經典演算法學習 堆排序
堆排序是相對其他排序稍微麻煩的排序,是一種利用堆的性質進行的選擇排序。堆其實是一棵完全二叉樹,只要任何乙個非葉節點的關鍵字不大於或者不小於其左右孩子節點,就可以形成堆。堆分為大頂堆和小頂堆。由上述性質可知大頂堆的堆頂的關鍵字是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的。堆排序同快速...
演算法學習之 堆排序
1.堆是實現優先佇列的首選資料結構,最常見的是二叉堆。2.堆的性質 小頂堆 每乙個父節點的值總是不大於它的孩子節點的值。大頂堆 每乙個父節點的值總是不小於它的孩子節點的值。堆包含的操作有 insert 插入操作 extractmin 提取最小 用於小頂堆 exectractmax 提取最大 用於大頂...