堆的概念:
堆是一種完全二叉樹,就是除了最後一層之外的其他每一層都被完全填充,並且所有結點都保持向左對齊的樹。就像碼金字塔的磚塊,必須從頭到底,從左到右乙個乙個碼,不能空缺。
堆有兩種型別:大根堆,小根堆
大根堆:每個結點的值都大於或等於左右孩子結點
小根堆:每個結點的值都小於或等於左右孩子結點
大根堆:
小根堆
大根堆構建流程:
先依據構建乙個完全二叉樹
此處並沒有構造實際的二叉樹,而是邏輯上:
import math
def print_tree(array):
'''前空格元素間
170237
3134 01
'''index = 1
depth = math.ceil(math.log2(len(array))) # 因為補0了,不然應該是math.ceil(math.log2(len(array)+1))
sep = ' '
for i in range(depth):
offset = 2 ** i
print(sep * (2 ** (depth - i - 1) - 1), end='')
line = array[index:index + offset]
for j, x in enumerate(line):
print("}".format(x, len(sep)), end='')
interval = 0 if i == 0 else 2 ** (depth - i) - 1
if j < len(line) - 1:
print(sep * interval, end='')
index += offset
print()
# heap sort
# 為了和編碼對應,增加乙個無用的0在首位
origin = [0, 30, 20, 80, 40, 50, 10, 60, 70, 90]
total = len(origin) - 1 # 初始待排序元素個數,即n
print_tree(origin)
列印結果:
3020 80
40 50 10 60
70 90
調整完全二叉樹中的堆節點
1)度數為2的結點a,如果它的左右孩子結點的最大值比它大的,將這個最大值和該結點交換
2)度數為1的結點a,如果它的左孩子的值大於它,則交換
3)如果結點a被交換到新的位置,還需要和其孩子結點重複上面的過程
def heap_adjust(n, i, array: list):
'''調整當前結點(核心演算法)
調整的結點的起點在n//2,保證所有調整的結點都有孩子結點
:param n: 待比較數個數
:param i: 當前結點的下標
:param array: 待排序資料
:return: none
'''while 2 * i <= n:
# 孩子結點判斷 2i為左孩子,2i+1為右孩子
lchile_index = 2 * i
max_child_index = lchile_index # n=2i
if n > lchile_index and array[lchile_index + 1] > array[lchile_index]: # n>2i說明還有右孩子
max_child_index = lchile_index + 1 # n=2i+1
# 和子樹的根結點比較
if array[max_child_index] > array[i]:
array[i], array[max_child_index] = array[max_child_index], array[i]
i = max_child_index # 當前節點調整後,被交換的節點max_child_index所在的子堆,需要判斷是否還需要調整
else:
break
3.構建大根堆:
def max_heap(total,array:list):
for i in range(total//2,0,-1):
heap_adjust(total,i,array)
return array
print_tree(max_heap(total,origin))
結果: 90
70 80
40 50 10 60
20 30
構建完大根堆後,開始排序:
每次都要讓堆頂的元素和最後乙個結點交換,然後排除最後乙個元素,形成乙個新的被破壞的堆。
讓它重新調整,調整後,堆頂一定是最大的元素。
再次重複第1、2步直至剩餘乙個元素
def sort(total, array:list):
while total > 1:
array[1], array[total] = array[total], array[1]
print_tree(origin)# 堆頂和最後乙個結點交換
total -= 1
if total == 2 and array[total] >= array[total-1]:
break
heap_adjust(total,1,array)
print_tree(origin)
return array
print_tree(sort(total,origin))
結果: 10
20 30
40 50 60 70
80 90
資料結構 堆(python實現)
資料結構 堆 python實現 用list來儲存堆元素,表尾端加入元素,首段作為堆頂 借鑑裘老師資料結構與演算法的書加上自己的理解 堆 就是乙個完全二叉樹 class heap object def init self,elist self.elems list elist if elist sel...
基礎資料結構 堆
更新完了,但是細節說的還不太夠,以後再說吧 堆的本質是乙個完全二叉樹,除了最下面一層以外,其他的每層 假設第 n 層 都有 2 n 個結點。節點存的值每層都是遞增或者遞減的。遞增的話就是大頂堆,遞減的話就是小頂堆。那麼對於大頂堆來說,每個節點的兒子節點上的值都要小於等於該節點,否則它就不是乙個堆。堆...
資料結構 堆的實現
普通的模板引數 template struct less template struct greater template 預設為小堆 class heap heap const t array,size t size int root heap.size 2 1 for root 0 root s...