算法導論讀書筆記(6)
優先級隊列
堆的一個很常見的應用:做爲高效的 優先級隊列 (priority queue)。隊列也有兩種:最大優先級隊列和最小優先級隊列。html
優先級隊列 是一種用來維護由一組元素構成的集合 S 的數據結構,這一組元素中的每個都有一個關鍵字 key 。一個 最大優先級隊列 支持如下操做:java
INSERT(S, x)
:把元素 x 插入集合。MAXIMUM(S)
:返回 S 中具備最大關鍵字的元素。EXTRACT-MAX(S)
:去掉並返回 S 中具備最大關鍵字的元素。INCREASE-KEY(S, x, k)
:將元素 x 的關鍵字值增長到 k ,這裏 k 值不能小於 x 的原關鍵字值。
最大優先級隊列的一個應用是在一臺分時計算機上進行做業調度。 最小優先級隊列 支持的操做包括 INSERT
, MINIMUM
, EXTRACT-MIN
, DECREASE-KEY
。這種隊列可被用在基於事件驅動的模擬器中。算法
下面是最大優先級隊列的操做。過程 HEAP-MAXIMUM
用 Θ (1)的時間實現了 MAXIMUM
操做sql
HEAP-MAXIMUM(A) 1 return A[1]
過程 HEAP-EXTRACT-MAX
實現了 EXTRACT-MAX
操做。數組
HEAP-EXTRACT-MAX(A) 1 if A.heap-size < 1 2 error "heap underflow" 3 max = A[1] 4 A[1] = A[A.heap-size] 5 A.heap-size = A.heap-size - 1 6 MAX-HEAPIFY(A, 1) 7 reutrn max
HEAP-EXTRACT-MAX
的運行時間爲 O (lg n )。bash
過程 HEAP-INCREASE-KEY
實現了 INCREASE-KEY
操做。數據結構
HEAP-INCREASE-KEY(A, i, key) 1 if key < A[i] 2 error "new key is smaller than current key" 3 A[i] = key 4 while i > 1 and A[PARENT(i)] < A[i] 5 exchange A[i] with A[PARENT(i)] 6 i = PARENT(i)
下圖是 HEAP-INCREASE-KEY
操做的一個示例。在 n 元堆上, HEAP-INCREASE-KEY
的運行時間爲 O (lg n )。ide
下面的 MAX-HEAP-INSERT
過程實現了 INSERT
操做。post
MAX-HEAP-INSERT(A, key) 1 A.heap-size = A.heap-size + 1 2 A[A.heap-size] = -∞ 3 HEAP-INCREASE-KEY(A, A.heap-size, key)
該過程的運行時間也是 O (lg n )。spa
上述過程的參考實現。
練習
6.5-7
給出 HEAP-DELETE
的僞碼
HEAP-DELETE(A, i) 1 A[i] = A[A.heap-size] 2 A.heap-size = A.heap-size - 1 3 MAX-HEAPIFY(A, i)
6.5-8
給出一個時間爲 O ( n lg n ),用來將 k 個已排序鏈表合併成一個排序鏈表的算法。此處 n 爲全部鏈表中元素的總數。(用最小堆作 k 路合併)
問題思路:首先將 k 個已排序鏈表中的第一個元素取出並放入一個有 k 個元素的數組中,接着使用該數組構造最小堆。而後使用 HEAP-EXTRACT-MIN
過程每次從堆中取出一個元素放入新鏈表中,而後再從取出元素的原鏈表中取出下一個元素放入堆中,重複以上步驟直到堆爲空。最終的新鏈表中保存的就是已排序的全部元素。