切換
舊版
前往
大廳
主題

CH. 1.0 - Heap

鄧董 | 2020-09-20 02:48:35 | 巴幣 2 | 人氣 739

原本想先從Fibonacci heap著手,突然想到heap本身其實也很值得紀錄一番,遂由此而起。



Heap : 中文又稱"堆積",常見的為二元堆積(Binary Heap),是一由大到小 or 由小到大的二元樹結構。

Mergeable : 任何data structures可以支援以下5種操作,且所有elements都有key;
  1. MAKE-HEAP ()
  2. INSERT (H , x)
  3. MINIMUM (H)
  4. EXTRACT-MIN (H)
  5. UNION (H1 , H2)

Heap property : H[ Parent(i) ] ≤ or ≥ H[ i ] , ∀ i ∈ Index

Heap最簡單的實作方式為使用array,可說是相當簡單就能使用並廣泛運用在任何需要的地方,以下都以array implement。


Note : 由於應對之後使用多是為minimum form,所以以下思路以此為主;log底數皆為2。

  • Heapify的精神 : 把一node所有children與其相比,如果較大/小就把index存起來,遍歷完成後檢查index是否跟parent相符,不符就互換,並遞迴執行Heapify(H , index)。

HEAPIFY (H , i)
l = LEFT (i)
r = RIGHT (i)
if l ≤ H.heap-size and H[ l ] < H[ i ]
smallest = l
else smallest = i
if r ≤ H.heap-size and H[ r ] < H[ smallest ]
smallest = r
if smallest ≠ i
exchange H[ i ] with H[ smallest ]
HEAPIFY (H , smallest)

Recurrence : T (n) ≤ T (2n/3) + Θ (1)
Note : 2n/3為worst case,tree的一邊half-full situation.

Time complexity : O (log n)
從recurrence可得出 or Master theorem。


  • Build-Heap的精神 : 利用上述的Heapify,給定heap-size來建構一個heap。

BUILD-MIN-HEAP (H)
H.heap-size = H.length
for i = H.length/2 downto 1
HEAPIFY (H , i)

Recurrence : T (n) ≤ 2T (n/2) + log n
Note : 由root開始,h=1有兩個nodes,故要multiply by 2,其餘依此類推。

Time complexity : O (n)
證明 (從recurrence得出 or 根據heap大小--leaf*height--得出)。


  • HeapSort 的精神 : 把最後一個element與root交換,提出最後一個element後再對root做Heapify,重複到最後可得出由大到小的排列。

HEAPSORT (H)
BUILD-MIN-HEAP (H)
for i = H.length downto 2
exchange H[ 1 ] with H[ i ]
H.heap-size --
HEAPIFY (H , 1)

Time complexity : O (nlog n)
Build-Heap使用了O (n),for迴圈使用了n-1次,而Heapify為 log n,其餘為constant time,故為 O (n) + (n - 1)*(log n +C) = O (nlog n)




Priority queues : 一種data structure處理 set,作為heap的一種延伸應用,可以處理INSERT、MINIMUM、EXTRACT-MIN、INCREASE-KEY等operations。

Note : priority queue應用層面相當廣泛,課本中舉例為event-driven simulator,使用Extract Min 來選擇優先發生的事件作處理,Insert把新事件插入priority queue中;或是scheduler、pipeline manager之類需要取前後順序的系統都能使用上,而且在插入、刪除node的速度不慢,也適合套用在各類演算法中。

  • Minimum/Maximum的精神 : 由於heap已經定義好max/min了,直接取root即可。

HEAP-MINIMUM
return H[ 1 ]

Time complexity : Θ (1)
Trivial.


  • Extract Min的精神 : 使用HeapSort中把root與最後一個element調換並提出的技巧,把min提出,亦即是,做一次的HeapSort。

HEAP-EXTRACT-MIN (H)
if H.heap-size < 1
error "heap underflow"
min = H[ 1 ]
H[ 1 ] = H[ H.heap-size ]
H.heap-size --
HEAPIFY (H , 1)
return min

Time complexity : O (log n)
Trivial.


  • Increase Key的精神 : 由於改變element's key可能會導致不符合heap結構邏輯,然而真正影響的只有ancestors,sibling or offspring不會受影響,所以只要trace back parents即可。

HEAP-INCREASE-KEY (H , i , key)
if key < H[ i ]
error "new key is smaller than current key"
H[ i ] = key
while i > 1 and H[ Parent (i) ] > H[ i ]
exchange H[ i ] with H[ Parent (i) ]
i = Parent (i)
Time complexity : O (log n)
從current node trace back to root總共路徑長為樹高,則h = log n。 note : 不會為O (n)的原因為heap是一種 binary complete tree。


  • Heap Insert的精神 : 先設一個key = −∞ 的element,並加在heap末端,再對其做Increase Key。
  • 由於Increase Key已經處理結構邏輯問題,故不需要Heapify

HEAP-INSERT(H , Key)
H.heap-size ++
H[ H.heap-size ] = −∞
HEAP-INCREASE-KEY(H , H.heap-size , key)

Time complexity : ⇔ Increase Key = O (log n)


末碎碎念:
沒想到心血來潮寫個heap花一堆時間,打文章要注意排版真是麻煩,而且巴哈排版又特別難用,應該使用hackmd 或 medium再貼上才對哈哈,不過算啦,這篇也算是搞懂了怎麼使用,之後應該會上手很多。


Ref :
  1. T. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein, Introduction to Algorithms, third edition, the MIT press, 2009
  2. B. F. Wang, 上課講義

創作回應

末法行者
完全看不懂
2020-09-20 03:10:40
末法行者
救命
2020-09-20 03:10:43
鄧董
要去讀這個應該至少要修過資結才會有概念
2020-09-21 01:49:16
末法行者
我去看看能不能修
2020-09-21 09:28:18
Dannydaay
感謝你提供中翻的各種有關heap的算法 考生路過
2022-11-01 14:25:14

更多創作