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 是最小值。

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

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 Anthony DELANOIX on Unsplash
Read More

Union Find

Union Find data structure 又稱 disjoint set data structure。它是一個資料結構,用來儲存一堆 disjoint set。它提供兩個操作,一個是用來合併兩個 sets,另一個是用來尋找給定元素的 set。
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