STL源码剖析——容器配接器之priority_queue
来源:互联网 发布:中情局又遭曝光 知乎 编辑:程序博客网 时间:2024/05/18 02:51
前言
priority_queue是拥有优先级的queue,不过它容器内的元素并不是根据加入顺序排列,而是根据用户定义的优先级进行排列。priority_queue只能在队列尾部加入元素,在头部取出元素。不能遍历容器,因此不需要自己设置迭代器。在SGI STL的源码<stl_queue.h>的class priority_queue设计中,它是基于某种容器作为底部结构的,默认容器是vector容器,用户也可以自己指定容器的类型。
priority_queue容器配接器
下面给出源码剖析:
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 { // requirements: __STL_CLASS_REQUIRES(_Tp, _Assignable); __STL_CLASS_REQUIRES(_Sequence, _Sequence); __STL_CLASS_REQUIRES(_Sequence, _RandomAccessContainer); typedef typename _Sequence::value_type _Sequence_value_type; __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type); __STL_CLASS_BINARY_FUNCTION_CHECK(_Compare, bool, _Tp, _Tp);public:// priority_queue仅支持对头部和尾部的操作, 所以不定义STL要求的 // pointer, iterator, difference_type 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;//底层容器,默认为vector,用户可自行指定容器类型 _Compare comp;//优先级决策方式public://***********************************************************//*构造函数//*priority_queue() //*explicit priority_queue(const Compare& __x) //*explicit priority_queue (const Compare& comp = Compare(), //* const Container& ctnr = Container());//*template <class InputIterator> //* priority_queue (InputIterator first, InputIterator last, //* const Compare& comp = Compare(), //* const Container& ctnr = Container());//*********************************************************** priority_queue() : c() {} explicit priority_queue(const _Compare& __x) : c(), comp(__x) {} priority_queue(const _Compare& __x, const _Sequence& __s) : c(__s), comp(__x) { make_heap(c.begin(), c.end(), comp); }#ifdef __STL_MEMBER_TEMPLATES template <class _InputIterator> priority_queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) { make_heap(c.begin(), c.end(), comp); } template <class _InputIterator> priority_queue(_InputIterator __first, _InputIterator __last, const _Compare& __x) : c(__first, __last), comp(__x) { make_heap(c.begin(), c.end(), comp); } template <class _InputIterator> priority_queue(_InputIterator __first, _InputIterator __last, const _Compare& __x, const _Sequence& __s) : c(__s), comp(__x) { c.insert(c.end(), __first, __last); make_heap(c.begin(), c.end(), comp); }#else /* __STL_MEMBER_TEMPLATES */ 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); }#endif /* __STL_MEMBER_TEMPLATES */ //判断容器是否为空 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); push_heap(c.begin(), c.end(), comp); } __STL_UNWIND(c.clear()); } //弹出优先级最高的元素 void pop() { __STL_TRY { pop_heap(c.begin(), c.end(), comp); c.pop_back(); } __STL_UNWIND(c.clear()); }};// no equality is provided__STL_END_NAMESPACE#endif /* __SGI_STL_INTERNAL_QUEUE_H */// Local Variables:// mode:C++// End:举例说明该容器的使用:
// constructing priority queues#include <iostream> // std::cout#include <queue> // std::priority_queue#include <vector> // std::vector#include <functional> // std::greaterclass 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}; std::priority_queue<int> first; std::priority_queue<int> second (myints,myints+4); std::priority_queue<int, std::vector<int>, std::greater<int> > third (myints,myints+4); std::cout << "third = ( "; while ( !third.empty( ) ) { std::cout << third.top( ) << " "; third.pop( ); } std::cout << ")" << std::endl; // using mycomparison: typedef std::priority_queue<int,std::vector<int>,mycomparison> mypq_type; mypq_type fourth (myints,myints+4); // less-than comparison mypq_type fifth (mycomparison(true)); // greater-than comparison std::cout << "fourth = ( "; while ( !fourth.empty( ) ) { std::cout << fourth.top( ) << " "; fourth.pop( ); } std::cout << ")" << std::endl; std::cout << "fifth = ( "; while ( !fifth.empty( ) ) { std::cout << fifth.top( ) << " "; fifth.pop( ); } std::cout << ")" << std::endl; for (int i = 0; i < 5; i++) { fifth.push(i*10); }std::cout <<"after push the elements,fifth size is :"<<fifth.size()<<std::endl; std::cout << "after push the elements,fifth = ( "; while ( !fifth.empty( ) ) { std::cout << fifth.top( ) << " "; fifth.pop( ); } std::cout << ")" << std::endl; system("pause"); return 0;}Output:third = ( 10 20 50 60 )fourth = ( 60 50 20 10 )fifth = ( )after push the elements,fifth size is :5after push the elements,fifth = ( 0 10 20 30 40 )参考资料:
《STL源码剖析》侯捷
0 0
- STL源码剖析——容器配接器之priority_queue
- STL之priority_queue源码剖析
- STL源码剖析 [容器](八)[priority_queue]
- STL源码剖析——priority_queue
- STL源码剖析——容器配接器之stack
- STL源码剖析——容器配接器之queue
- STL 之 queue、priority_queue 源码剖析
- STL源码—priority_queue
- 【STL源码剖析读书笔记】【第4章】序列式容器之heap和priority_queue
- STL 源码剖析读书笔记五:序列式容器之 heap、priority_queue、slist
- STL源码剖析-序列式容器之heap和priority_queue
- STL源码剖析 - 第4章 序列式容器 - priority_queue
- 【STL】顺序容器 — priority_queue
- STL源码剖析——序列容器之vector
- STL源码剖析——序列容器之list
- STL源码剖析——序列容器之deque
- STL源码剖析——关联容器之set
- STL源码剖析——关联容器之map
- Oracle中start with...connect by 子句的用法
- android:ListView的局部刷新
- HDFS 文件操作
- 编程算法 - 最小能被1至n整除的数 代码(C)
- 有关ivy
- STL源码剖析——容器配接器之priority_queue
- Oracel数据库连接时出现:ORA-12518:监听程序无法分发客户机连接
- Base64算法详解和实现【备忘】
- a 去掉小手
- 【Python Challenge-11】5808
- Binary Tree Postorder Traversal
- ubuntu终端su认证失败(Authentication), 允许su到root的方法
- win 7 IIS Web服务器安装配置过程中的常见问题及解决方案
- tomcat log 配置解决catalina.out文件过大问题