堆 (heap) 是一種經過排序的完全二叉樹,其中任一非葉子節點的值均不大於(或不小於)其左孩子和右孩子節點的值。
注:定義來自百度百科。
堆,又被為優先隊列(priority queue)。盡管名為優先隊列,但堆並不是隊列。
其他概念解釋
-
最大堆 根結點的鍵值是所有堆結點鍵值中最大者。
-
最小堆 根結點的鍵值是所有堆結點鍵值中最小者。
最小堆

最大堆

基本功能介紹及實現
在接下來的內容里,我們將逐步介紹堆的具體功能是如何實現的。
堆有兩點需要了解,一是堆一般采用完全二叉樹;二是堆中的每一個節點都大於其左右子節點(大頂堆),或者堆中每一個節點都小於其左右子節點(小頂堆)。
1. 創建 heap 類
class heap(object):
def __init__(self):
#初始化一個空堆,使用數組來在存放堆元素,節省存儲
self.data_list = []
2. 添加 get_parent_index 函數
def get_parent_index(self,index):
#返回父節點的下標
if index == 0 or index > len(self.data_list) -1:
return None
else:
return (index -1) >> 1
3. 添加 swap 函數
def swap(self,index_a,index_b):
#交換數組中的兩個元素
self.data_list[index_a],self.data_list[index_b] = self.data_list[index_b],self.data_list[index_a]
4. 添加 insert 函數
def insert(self,data):
#先把元素放在最后,然后從后往前依次堆化
#這里以大頂堆為例,如果插入元素比父節點大,則交換,直到最后
self.data_list.append(data)
index = len(self.data_list) -1
parent = self.get_parent_index(index)
#循環,直到該元素成為堆頂,或小於父節點(對於大頂堆)
while parent is not None and self.data_list[parent] < self.data_list[index]:
#交換操作
self.swap(parent,index)
index = parent
parent = self.get_parent_index(parent)
5. 添加 removeMax 函數
def removeMax(self):
#刪除堆頂元素,然后將最后一個元素放在堆頂,再從上往下依次堆化
remove_data = self.data_list[0]
self.data_list[0] = self.data_list[-1]
del self.data_list[-1]
#堆化
self.heapify(0)
return remove_data
6. 添加 heapify 函數
def heapify(self,index):
#從上往下堆化,從index 開始堆化操作 (大頂堆)
total_index = len(self.data_list) -1
while True:
maxvalue_index = index
if 2*index +1 <= total_index and self.data_list[2*index +1] > self.data_list[maxvalue_index]:
maxvalue_index = 2*index +1
if 2*index +2 <= total_index and self.data_list[2*index +2] > self.data_list[maxvalue_index]:
maxvalue_index = 2*index +2
if maxvalue_index == index:
break
self.swap(index,maxvalue_index)
index = maxvalue_index
