Priority Queue & Heap

Photo by Simon Hermans on Unsplash
Photo by Simon Hermans on Unsplash
Priority queue 是一個很好用的 data structure。它可以在常數時間內提供最大或最小值。在了解它之前,我們要先了解另一個 data structure 叫 heap。因為 priority queue 常常會用 heap 來實作。

Priority queue 是一個很好用的 data structure。它可以在常數時間內提供最大或最小值。在了解它之前,我們要先了解另一個 data structure 叫 heap。因為 priority queue 常常會用 heap 來實作。

Heap

Heap data structure 是一個 array,我們可以將它視為一個 complete binary tree。我們用 A[1:n] 表示 heap 的 array,所以 A 是一個大小為 n 的 array。A 的 index 從 1 開始。A.heapSize 表示有 heapSize 個元素儲存在 A 裡面,所以 0 \le heapSize \le n。下圖顯示一個 max-heap 以 tree 的方式呈現,以及它的元素如何儲存在 array 裡。

From Introduction to Algorithms, 4th Ed.
From Introduction to Algorithms, 4th Ed.

因為 heap 實際上是一個 array,但我們卻會將它當成一個 complete binary tree。所以,對一個 node i 也就是 index i,我們常常需要取得它的 parent、left child、和 right child。

Parent(i) {
    return floor(i / 2)
}

Left(i) {
    return 2 * i
}

Right(i) {
    return 2 * i + 1
}

Heap Property

Heap 有兩種,一種是 max-heap,另一種是 min-heap。Max-heap 的 property 是,對於每一個 node i,它的值比它的 subtree 裡所有 node 的值大。反之,min-heap 的 property 是,對於每一個 node i,它的值比它的 subtree 裡的所有 node 的值小。所以,max-heap 的 root 是最大值;而 min-heap 的 root 是最小值。

\text{max heap property}: A[Parent(i)] \ge A[i]

\text{min heap property}: A[Parent(i)] \le A[i]

維護 Heap Property

每個 heap 都要滿足它的 property。當一個 heap 違反它的 property 時,我們需要一個 procedure 來使 heap 滿足它的 property。我們可以用以下的 MaxHeapify 來使一個 subtree 滿足 max-heap property。

MaxHeapify 的輸入是 heap 的 array 和 index i。如果 node i 違反 max-heap property 的話,它可以使得 node i 和它 subtree 滿足 max-heap property。MaxHeapify 比較 node i 與它的 left 和 right children,並將 node i 與最大的 child 交換,然後再 recursively 對被交換的 child 做相同的動作。MaxHeapify 的時間複雜度為 O(h),其中 h 為樹的高度。

Algorithm MaxHeapify(A, i) {
    left := Left(i)
    right := Right(i)

    if left <= A.heapSize && A[left] > A[i] {
        largest := left
    } else {
        largest := i
    }

    if right <= A.heapSize && A[right] > A[largest] {
        largest := right
    }

    if largest != i {
        swap(A[i], A[largest])
        MaxHeapify(A, largest)
    }
}

以下的範例是對 index 2 的 node 做 MaxHeapify(A, 2)。

From Introduction to Algorithms, 4th Ed.
From Introduction to Algorithms, 4th Ed.

建立 Heap

下面的演算法 BuildMaxHeap 是將一個 array A[1:n] 轉換成一個 max-heap。它的時間複雜度是 O(n log n)

Algorithm BuildMaxHeap(A, n) {
    A.heapSize := n
    for i := floor(n / 2) to 1 {
        MaxHeapify(A, i)
    }
}
From Introduction to Algorithms, 4th Ed.
From Introduction to Algorithms, 4th Ed.

Priority Queue

Priority queue 是一個 data structure,且維護一群元素集合 S。Priority queue 有兩種,一種是 max-priority queue,另一種是 min-priority queue。一個 max-priority queue 提供以下操作:

  • Max(S):回傳 S 中的最大值。
  • ExtractMax(S):移除並回傳 S 中的最大值。
  • Insert(S, x):將 x 加入到 S 中。

因為 max-priority queue 的 Max(S) 和 ExtractMax(S),所以我們可以用 max-heap 來實作 max-priority queue。以下是 max-priority queue 的演算法,其中 A 表示 max-heap 的 array。另外,它們的時間複雜度如下:

  • Max(A): O(1)
  • ExtractMax(A): O(log n)
  • Insert(A, x): O(log n)
Algorithm Max(A) {
    if A.heapSize < 1 {
        error "heap underflow"
    }
    return A[1]
}

Algorithm ExtractMax(A) {
    max := Maximum(A)
    A[1] := A[A.heapSize]
    A.heapSize := A.heapSize - 1
    MaxHeapify(A, 1)
    return max
}

Algorithm Insert(A, x) {
    if A.heapSize == A.size {
        error "A has no room for x"
    }
    A.heapSize := A.heapSize + 1
    A[A.heapSize] = x
    i := A.heapSize
    while i > 1 && a[Parent(i)] < x {
        swap(A[i], A[Parent(i)])
        i := Parent(i)
    }
}

參考

  • Ellis Horowitz, Sartaj Sahni, Sanguthevar Rajasekaran, Computer Algorithm.
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein, Introduction to Algorithms, 4th Ed.
發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

You May Also Like
Photo by Léonard Cotte on Unsplash
Read More

Depth First Search (DFS)

深度優先搜尋(DFS)演算法是一種圖形搜尋演算法。從給定的一個點開始,它會先探索該點的一個相鄰點。再來,探索該相鄰點的一個相鄰點。這樣子一直探索下去,直到某的點沒有相鄰點時,它就會退回到上一個點,並探索該點的下一個相鄰點。它會一直這樣地探索下去,直到找到結果,或是探索完所有的點。
Read More
Photo by Pedro Lastra on Unsplash
Read More

Breadth First Search (BFS)

廣度優先搜尋(BFS)演算法是一種圖形搜尋演算法。從給定的一個點開始,它會先探索該點所有的相鄰點。再來,依序探索這些相鄰點的相鄰點。這樣子一層一層地探索下去,直到找到結果,或是探索完所有的點。
Read More
Photo by Folco Masi on Unsplash
Read More

Binary Search Tree

二元搜尋樹(Binary search tree, BST)是一種二元樹(binary tree)。它提供了一些有用操作,包含 search、insert、delete、minimum、maximum、successor 和 predecessor。
Read More
Photo by Anthony DELANOIX on Unsplash
Read More

Union Find

Union Find data structure 又稱 disjoint set data structure。它是一個資料結構,用來儲存一堆 disjoint set。它提供兩個操作,一個是用來合併兩個 sets,另一個是用來尋找給定元素的 set。
Read More