一般來說,短的作業要盡可能地快速結束,這很重要,是以在已經運作的作業當中這些短作業應該擁有優先權。此外,有些作業雖然不短小但很重要,也應該有優先權。
6.1 模型
優先隊列是允許至少以下兩種操作的資料結構:insert(插入),它的作用是插入一個元素;以及deleteMin(删除最小者元素),它的工作是找出、傳回并删除優先隊列中最小的元素。insert操作等價于enqueue(入隊),而deleteMin操作等價于dequeue(出隊)。
在貪婪算法的實作方面隊列也是很重要的,該算法通過反複求一個最小元來進行操作。
6.2 一些簡單的實作
一種實作優先隊列的方法是使用二叉樹,它對這兩種操作的平均運作時間都是O(logN)。
缺陷: 在使用二叉查找樹來實作優先隊列的時候,我們删除的唯一進制素是最小元。反複除去左子樹的節點似乎會損害樹的平衡、使得右子樹加重。然而,右子樹是随機的。在最壞的情況下,即deleteMin将左子樹删空的情況下,右子樹擁有的元素最多就是它應具有的兩倍。
6.3 二叉堆
二叉堆:像二叉查找樹一樣,堆也有兩個性質,即結構性和堆序性。恰似AVL樹,對堆的一次操作可能破快這兩個性質中的一個,是以,堆的操作必須到堆的所有性質都被滿足時才能終止。
6.3.1 結構性質
堆是一顆被完全填充的二叉樹。容易證明一個高為h的完全二叉樹有2k到2(k+1)-1個節點。這意味着二叉樹的高是[logN],顯然他是O(logN)
二叉堆的實作可以用一數組來實作:
是以一個堆的結構将由一個(Compareable對象的)數組和一個代表目前堆的大小的整形數組組成。
6.3.2 堆序性質
在一個堆中,對于每個節點X,X的父親中的關鍵字小于或則等于X的關鍵字,根節點除外(它沒有父親)。
6.3.3 基本的堆操作
insert(插入)
insert操作一般的政策叫做上濾。為将一個元素插入到堆中,我們在下一個可用的位置建立一個空穴,否則該堆就不是完全樹。如果X可以放入空穴中而不破快堆的序,那麼插入完成。否則,我們把空穴的父節點上的元素移入該空穴中,這樣,空穴就朝着根的方向向上冒一步。
deleteMin(删除最小元)
deleteMin操作的一般政策叫做下濾。當删除一個最小元的時候,要在根節點建立一個空穴。由于堆中現在少了一個元素了,是以堆中最後一個元素X必須移動到該堆的某個地方。如果X可以被放入到空穴中,那麼deleteMin操作完成。不過這一般都不太可能,是以我們将空穴的兩個兒子中較少者放入空穴,這樣就把空穴向下推了一層。重複該步驟直到X可以被放入空穴中。是以,我們的做法就是将X置入沿着從根開始包含最小兒子的一條路徑上的正确位置。
6.3.4 其他堆的操作
decreaseKey(降低關鍵字的值)
decreaseKey(p,∆)降低在位置p處的項的值,降低幅度為正的量∆,由于這可能破壞堆序性質,是以必須通過上濾操作來對堆進調整。
increaseKey(增加關鍵字的值)
iecreaseKey(p,∆)操作增加在位置p處的項的值,增值的幅度為正的量∆。這可以用下濾來完成,許多排程程式自動地降低正在過多地消耗CPu時間内程序的優先級。
delete(删除)
delete§操作删除堆中位置p上的節點。該操作首先執行decreaseKey(p,無窮大),然後再執行deleteMin()操作來完成。
buildHeap(建構堆)
有時候二叉堆是由一些的初始集合構造而得。這種構造方法以N作為輸入項,并把他們放到一個堆中。
6.9 标準庫中的優先隊列
然而在Java 1.5中出現了泛型類的PriorityQueue,在該類中insert、findMin和deleteMin通過add、element和remove表示。PriorityQueue對象可以通過無參數、一個比較器、或另一個相容的結合構造出來。
由于優先隊列有許多有效的實作方法,是以該類庫的設計者沒有選擇讓PriorityQueue成為一個接口。