一、概述
priority_queue,首先它是一个queue,即只允许在低端加入元素,并从顶端取出元素,除此之外别无其他存取元素的途径(故priority_queue不提供遍历功能,也不提供迭代器);再次它具有priority,即queue中的元素具有一定的priority:其内的元素自动依照元素的权值排列,权值最高者(也就是数值最高),排在最前面。
注:在queue并非是依照严格的权值递减的顺序排列,而是每次保持顶端(对头)元素为queue中权值最高的元素(其内部采用heap来实现(默认是max heap))。
二、实现
由于priority_queue完全以底部容器为根据,在加上heap处理规则,所以其实现较简单,且缺省情况下以vector为底部容器。
联系适配器(adapter)的定义:具有这种【修改某物接口,形成另一种风貌】之性质者,称为adapter。因为,STL priority_queue被归类为:container adapter 。
其SGI(Silicon Graphics Computer Systems, Inc.) STL中的priority_queue的源码如下:
template<class T, class Sequeue = vector<T>, class Compare = less<typename Sequeue::value_type> > class priority_queue { public: typedef typename Sequeue::value_type value_type; typedef typename Sequeue::size_type size_type; typedef typename Sequeue::reference reference; typedef typename Sequeue::const_reference const_reference; protected: Sequeue c; //底层容器 Compare comp; //元素大小比较标准 public: priority_queue(): c() { } explicit priority_queue(const Compare& x) : c(), comp(x) {} template<class InputIterator> priority_queue(InputIterator first, InputIterator last, const Compare& x) :c(first, last), comp(x){make_heap(c.begin(), c.end(), comp); } priority_queue(InputIterator first, InputIterator last) //使用默认的comp比较标准 :c(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 { c.push_back(x); //先加入容器(vector) push_heap(c.begin(), c.end(), comp); //再利用heap对容器排序 } __STL_UNWIND(c.clear()); } void pop() { ———STL_TRY { pop_heap(c.begin(), c.end(), comp); //先退出heap(排序) c.pop_back(); //再从容器中删除 } __STL_UNWIND(c.clear()); } };
注:
class Compare = less<typename Sequeue::value_type>中的less对应大顶堆,即用parent与holeIndex值比较,若小于则percolate up:调整洞号,向上提升值父节点。---见《STL源码剖析》P175。
三、测试实例
#include <iostream> #include <queue> using namespace std; class myComparison { bool reverse; public: myComparison(const bool& revParam = false) { reverse = revParam; } bool operator()(const int& lhs, const int& rhs) const { if(reverse) return (lhs > rhs); else return (lhs < rhs); } }; int main() { int myInts[] = {10, 60, 50 ,20}; priority_queue<int> first; priority_queue<int> second(myInts, myInts+4); cout << "second size: " << second.size() << endl; cout << "second top: " << second.top() << endl; second.push(100); cout << "second top: " << second.top() << endl; priority_queue<int, vector<int>, greater<int> > third(myInts, myInts+4); cout << "third size: " << third.size() << endl; cout << "third top: " << third.top() << endl; third.push(100); cout << "third top: " << third.top() << endl; //using myComparison priority_queue<int, vector<int>, myComparison > fourth; typedef priority_queue<int, vector<int>, myComparison> myPq_type; myPq_type fifth(myComparison() ); myPq_type sixth(myInts, myInts+4, myComparison(true) ); cout << "sixth top: " << sixth.top() << endl; sixth.pop(); cout << "sixth top: " << sixth.top() << endl; return 0; }
输出结果:
References
<<STL 源码剖析>>
class tmplate std::priority_queue