標籤:演算法 優先順序隊列
優先順序隊列是容器的一種,可以向優先順序隊列中添加或取出資料,取出資料時只能取出最大的數或最小的數。而其他的一些容器比如隊列和棧,取出的順序跟插入的順序是有關的。
優先順序隊列的介面如下:
public class MaxPQ<Key extends Comparable<Key>> { MaxPQ(); void insert(Key x); Key popMax(); boolean isEmpty();}
優先順序隊列的應用
棧和隊列是優先順序隊列的特殊情況
問題舉例
現在有一個很大的txt檔案,檔案中包含了許多整數,檔案中的資料量非常大,無法將整個檔案讀取到記憶體中。求該檔案中最大的5個整數。
解答
這個問題就要用優先順序隊列進行求解,每次讀取一行,將資料加入到優先順序隊列,如果隊列的長度大於5,就刪除最小的元素。當整個檔案讀取完畢時,優先順序隊列中剩餘的元素就是要求的最大5個數。
複雜度
設需要在N個資料中求出最大的M個元素。
如果用排序演算法進行求解,時間複雜度是N logN,空間複雜度是N。
如果用基礎優先順序隊列進行求解,時間複雜度是N logM,空間複雜度為M。
如果用堆的資料結構來做,那麼時間複雜度是N logM,空間複雜度是M。
理論上能達到最小的時間複雜度是N,空間複雜度是M。
使用堆的演算法來求解該問題時,它的複雜度已經非常接近理論極限了。
代碼
下面展示了最簡單的優先順序隊列實現方法。插入的複雜度是1,刪除的複雜度是N。
public class UnorderedPQ<Key extends Comparable<Key>> { private Key[] items; private int N; public UnorderedPQ(int capacity) { items = (Key[])new Comparable[capacity]; } public void insert(Key item) { items[N] = item; N++; } public Key popMax() { // 找出最大的數字 int max = 0; for(int i=1;i<N;i++){ if(SortUtil.less(items[max], items[i])) { max=i; } } // 刪除最大的數字 Key result = items[max]; SortUtil.exch(items, max, N-1); // 注意:這裡是N-1,不是N N--; // 返回最大的數 return result; } public boolean isEmpty() { return N==0; }}