優先隊列Priority Queue和堆Heap
對COMP20003中的Priority queue部分進行總結。圖片來自於COMP20003
queue隊列,顧名思義特點先進先出
priority queue優先隊列,出來的順序按照優先級priority大小,越大(小)的先pop。
普通的方法:
Unsorted array:
Construct: O(n)
Get highest priority: O(n)
Sorted array:
Construct: O(n2)
Get highest priority: O(1)
使用堆heap方法則可以:
Construct:O(n)
Get hishest priority: O(1)
heap data structre: 完全樹的數組(指針)形式(不一定是二叉樹)。其每個節點滿足優先級高於它的子節點。 本文主要講binary heap形式的。
從根節點開始編號放入數組中,為了後續操作方便,可以將數組[0]空出不用,從1開始(如上圖,下面的文字敘述也按從1開始,將數組叫做A),因為完全樹的關系,如果一個節點是A[i],則它的兩個子節點則是A[2 * i]和A[2 * i + 1]。
假定優先級越高越靠前,則第一個節點是(優先級)最大的,之後的都比它小,但左子樹上的點和右子樹上的點大小關系並不確定。
當pop時,將第一個節點排出,將最後一個節點放到第一個節點的位置,然後從第一個節點位置開始進行downHeap操作修復堆(使得每個節點滿足優先級高於它的子節點)。
當push時,將新插入的節點接在末尾,從末尾開始進行upHeap操作修復堆(使得每個節點滿足優先級高於它的子節點)。
downHeap:從指定節點位置A[i]開始,與其兩個子節點A[2 * i]和A[2 * i + 1]進行優先級比較(或與兩個子節點中較大的那個進行比較),如果是A[i]最大,則停止,如果不是,則和較大的那個子節點交換位置,再繼續與子節點進行比較,直到沒有子節點時停止。
upHeap:從指定位置A[i]開始,與其根節點A[i / 2]進行比較,如果根節點大,則停止,否則交換位置繼續與根節點比較,直到沒有根節點為止。
兩種建堆方法:
1.插入一個節點,進行一次upHeap操作修復堆。 總復雜度O(nlogn)
2.將全部節點插入後,從A[n / 2]到A[1]進行upHeap操作修復堆,即heapSort。看似復雜度還是O(nlogn),但實際上是O(n),因為只有一半的節點需要進行upHeap操作且只有A[1]的upHeap是O(logn),數學證明不懂,以後看看有沒有時間補吧。。。
我的代碼:
https://raw.githubusercontent.com/Will-Zhu-27/Algorithms-and-Data-Structures/master/priorityQueue.c
https://raw.githubusercontent.com/Will-Zhu-27/Algorithms-and-Data-Structures/master/priorityQueue.h
優先隊列Priority Queue和堆Heap