資料結構基礎 python實現堆排序

2021-09-24 11:28:04 字數 3122 閱讀 3163

堆的概念:

堆是一種完全二叉樹,就是除了最後一層之外的其他每一層都被完全填充,並且所有結點都保持向左對齊的樹。就像碼金字塔的磚塊,必須從頭到底,從左到右乙個乙個碼,不能空缺。

堆有兩種型別:大根堆,小根堆

大根堆:每個結點的值都大於或等於左右孩子結點

小根堆:每個結點的值都小於或等於左右孩子結點

大根堆:

小根堆

大根堆構建流程:

先依據構建乙個完全二叉樹

此處並沒有構造實際的二叉樹,而是邏輯上:

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...