演算法學習 堆排序

2022-07-11 07:33:12 字數 2367 閱讀 2819

一、關於二叉樹和堆的基本概念

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]

print

(heapifysort(arr))#結果

[-111, -6, -3, 0, 8, 12, 12, 34, 88]

2、時間複雜度:o(nlogn)

排序演算法學習之堆排序

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

經典演算法學習 堆排序

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

演算法學習之 堆排序

1.堆是實現優先佇列的首選資料結構,最常見的是二叉堆。2.堆的性質 小頂堆 每乙個父節點的值總是不大於它的孩子節點的值。大頂堆 每乙個父節點的值總是不小於它的孩子節點的值。堆包含的操作有 insert 插入操作 extractmin 提取最小 用於小頂堆 exectractmax 提取最大 用於大頂...