1. 程式人生 > >優先佇列Priority Queue和堆Heap

優先佇列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