優先隊列從名字我們就可以猜到,其與隊列之間存在一定的練習,優先隊列與隊列一樣主要是入隊和出隊兩個操作。但是優先隊列與隊列的不同之處在於,優先隊列會將優先級高的先出隊,這在很多情況下非常有用。例如,Windows的MFC是基於消息的響應的機制,內部管理着一個消息隊列,計算機不斷從消息隊列中抓取消息進行響應,那么系統的消息和應用軟件的消息優先級必然不同,我們需要優先響應系統的消息,那么優先隊列就顯示它強大的功能。
堆的實現我們可以通過一個表,或者一個二叉樹都可以實現。如果通過一個表實現,入隊很方便,但是出隊,必須遍歷一遍表找到優先級最高的那個,需要花費O(N)的時間,效率太低。對於二叉樹來說入隊和出隊都是O(logN)的時間復雜度,但是二叉樹的頻繁刪除會導致樹向右邊傾斜,當然我們可以通過平衡樹來解決這個問題,但是對於優先隊列來說最簡單的方式是通過二叉堆實現。
二叉堆的實質是一個數組,只是我們用完全二叉樹的形式將其表述出來,完全二叉樹與不完全二叉樹的區別如下圖:

數組的第一位我們空出來是為了去滿足二叉堆的性質:設某元素所處於數組中的位置為i,那么他的左兒子的位置使2*i,他的父元素的位置在i/2;
因為對於堆來說插入比刪除要頻繁,因此將優先級最高的放在第一個,因為刪除比插入麻煩的多。
以下是例程,用vector實現:
1 /************************************************************************/ 2 /* 堆的實現 */ 3 /************************************************************************/ 4 #include<vector> 5 namespace stl 6 { 7 template<typename T> 8 class Heap 9 { 10 public: 11 /************************************************************************/ 12 /*構造函數*/ 13 Heap(int capacity = 100) 14 :size(0) //堆中包含數據個數 15 { 16 H.resize(capacity); 17 } 18 19 ~Heap() 20 { 21 } 22 23 bool isEmpty() 24 { 25 return size == 0; 26 } 27 28 void makeEmpty() 29 { 30 size = 0; 31 for (auto it = H.begin(); it != H.end(); it++) 32 { 33 H.erase(it); 34 } 35 } 36 /************************************************************************/ 37 /*插入函數 */ 38 void insert(const T & x) 39 { 40 //如果vector中已經存滿了,重新分為大小,數組首地址不存數據 41 if (size == H.size() -1) 42 { 43 H.resize(2*size); 44 } 45 //size大小加一 46 for (int current = ++size; current > 1 && H[current/2] > x; current /= 2) 47 { 48 H[current] = H[current/2]; 49 } 50 //找到空位將x插入 51 H[current] = x; 52 } 53 54 /*刪除函數*/ 55 T deleteMin() 56 { 57 if (isEmpty()) 58 { 59 throw(); 60 } 61 int current, child; 62 T returnVal = H[1]; 63 T lastElement = H[size--]; //將最后一個值保存下來,刪除一個元素所以自減運算 64 for (current = 1; 2 * current > size; current = child) 65 { 66 child = 2 * current; 67 //防止訪問越界 68 if (child != size && H[2 * current] > H[2 * current + 1]) 69 { 70 ++child; 71 } 72 //比較子較小的兒子與最后一個值的大小,如果兒子較小用兒子上濾,否則跳出循環 73 if (H[child] < lastElement) 74 { 75 H[current] = H[child]; 76 } 77 else 78 { 79 break; 80 } 81 } 82 H[current] = lastElement; 83 return returnVal; 84 } 85 86 private: 87 std::vector<T> H; 88 int size; 89 }; 90 }
