SGI STL優先佇列priority_queue
阿新 • • 發佈:2022-05-09
目錄
priority_queue簡介
跟普通queue不同的是,priority_queue擁有權值的概念,允許加入新元素、移除舊元素、檢視元素值等。priority_queue本身也是一個queue,因此只允許在尾部加入元素,頭部取出元素,除此外無法從別的位置存取元素。
普通queue是按先進先出的規則取出元素,內部儲存順序也是按進入先後順序排列;priority_queue並非如此排列,而是自動按元素的權值排列。權值最高值,排在最前面。
預設情況,priority_queue用一個max-heap實現,而priority_queue是以vector作為底部容器表現的complete binary tree(完全二叉樹)。因為max-heap可以滿足priority_queue所需的“依賴權值高低自動排序”的特性。
priority_queue資料結構
類似於stack、queue,priority_queue也是以底部容器完成操作的,加上heap處理規則。因此,STL中priority_queue往往不被歸類為container(容器),而被歸類為container adapter(容器介面卡)。
# define __STL_DEPENDENT_DEFAULT_TMPL(_Tp) = _Tp // 優先佇列 template <class _Tp, class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(vector<_Tp>), class _Compare __STL_DEPENDENT_DEFAULT_TMPL(less<typename _Sequence::value_type>) > class priority_queue { public: // 內嵌型別定義 typedef typename _Sequence::value_type value_type; typedef typename _Sequence::size_type size_type; typedef _Sequence container_type; typedef typename _Sequence::reference reference; typedef typename _Sequence::const_reference const_reference; protected: _Sequence c; // 底層容器 _Compare comp; // 比較子, 元素大小比較標準 public: priority_queue() : c() {} explicit priority_queue(const _Compare& __x) : c(), comp(__x) {} // 以下任意建構函式都立刻於底層容器內產生一個implicit representation heap // 因為呼叫了make_heap priority_queue(const _Compare& __x, const _Sequence& __s) : c(__s), comp(__x) { make_heap(c.begin(), c.end(), comp); } priority_queue(const value_type* __first, const value_type* __last) : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } priority_queue(const value_type* __first, const value_type* __last, const _Compare& __x) : c(__first, __last), comp(__x) { make_heap(c.begin(), c.end(), comp); } priority_queue(const value_type* __first, const value_type* __last, const _Compare& __x, const _Sequence& __c) : c(__c), comp(__x) { c.insert(c.end(), __first, __last); make_heap(c.begin(), c.end(), comp); } bool empty() const { return c.empty(); } size_type size() const { return c.size(); } const_reference top() const { return c.front(); } void push(const value_type& __x) { __STL_TRY { // push_heap 是泛型演算法, 先利用底層容器的push_back()將新元素 // 推入末端, 再重排heap c.push_back(__x); push_heap(c.begin(), c.end(), comp); // 泛型演算法 } __STL_UNWIND(c.clear()); // commit or clear all } void pop() { __STL_TRY { // pop_heap 是泛型演算法, 從heap內取出一個元素. 不是真正將元素彈出, 而是重排heap, // 然後再以底層容器的pop_back() 取得被彈出的元素. pop_heap(c.begin(), c.end(), comp); c.pop_back(); } __STL_UNWIND(c.clear()); // commit or clear all } }; # define __STL_TRY try # define __STL_CATCH_ALL catch(...) # define __STL_THROW(x) throw x # define __STL_RETHROW throw # define __STL_NOTHROW throw() # define __STL_UNWIND(action) catch(...) { action; throw; }
priority_queue測試例項
#include <queue> #include <iostream> #include <algorithm> using namespace std; int main() { { // test case1: test priority_queue int ia[9] = { 0,1,2,3,4,8,9,3,5 }; priority_queue<int> ipq{ ia, ia + 9 }; cout << "size = " << ipq.size() << endl; // size = 9 for (size_t i = 0; i < ipq.size(); i++) { cout << ipq.top() << ' '; // 9 9 9 9 9 9 9 9 9 } cout << endl; while (!ipq.empty()) { cout << ipq.top() << ' '; // 9 8 5 4 3 3 2 1 0 ipq.pop(); } cout << endl; } return 0; }