堆(heap) 亦被稱為:優先隊列(priority queue),是計算機科學中一類特殊的資料結構的統稱。堆通常是一個可以被看做一棵樹的數組對象。在隊列中,排程程式反複提取隊列中第一個作業并運作,因而實際情況中某些時間較短的任務将等待很長時間才能結束,或者某些不短小,但具有重要性的作業,同樣應當具有優先權。堆即為解決此類問題設計的一種資料結構。
n個元素序列{k1,k2...ki...kn},當且僅當滿足下列關系時稱之為堆:
(ki <= k2i, ki <= k2i+1)或者(ki >= k2i, ki >= k2i+1), (i = 1,2,3,4...n/2)
二叉堆一般用數組來表示。如果根節點在數組中的位置是1,第n個位置的子節點分别在2n和 2n+1。是以,第1個位置的子節點在2和3,第2個位置的子節點在4和5。以此類推。這種基于1的數組存儲方式便于尋找父節點和子節點。
如果存儲數組的下标基于0,那麼下标為i的節點的子節點是2i + 1與2i + 2;其父節點的下标是⌊(i − 1) ∕ 2⌋。
如下圖的兩個堆:
将這兩個堆儲存在以1開始的數組中:
二叉堆是完全二叉樹或者是近似完全二叉樹。
二叉堆滿足二個特性:
1.父結點的鍵值總是大于或等于(小于或等于)任何一個子節點的鍵值。
2.每個結點的左子樹和右子樹都是一個二叉堆(都是最大堆或最小堆)。
當父結點的鍵值總是大于或等于任何一個子節點的鍵值時為最大堆。當父結點的鍵值總是小于或等于任何一個子節點的鍵值時為最小堆。

最小堆 最大堆
堆支援以下的基本操作:
build:建立一個空堆;
insert:向堆中插入一個新元素;
update:将新元素提升使其符合堆的性質;
get:擷取目前堆頂元素的值;
delete:删除堆頂元素;
heapify:使删除堆頂元素的堆再次成為堆。
某些堆實作還支援其他的一些操作,如斐波那契堆支援檢查一個堆中是否存在某個元素。
此操作分3步:
(1)直接删除根
(2)用最後一個元素代替根
(3)将堆向下重新調整
輸出堆頂元素之後,以堆中最後一個元素替代之;然後将根結點值與左、右子樹的根結點值進行比較,并與其中小者進行交換;重複上述操作,直到是葉子結點或其關鍵字值小于等于左、右子樹的關鍵字的值,将得到新的堆。稱這個從堆頂至葉子的調整過程為“篩選”
調整堆算法實作如下:
删除最小元素,傳回該最小元素:
向上調整算法:
插入元素算法:
poj2051 argus