STL 笔记(三) 容器适配器 stack、queue、priority_queue

转载:http://blog.csdn.net/thisinnocence/article/details/39673043


栈 stack 

栈 stack 是一种先进后出的(First In Last Out, FILO)的数据结构。在 STL中,stack 底层容器默认使用的是deque, 也可以自己指定用 vector 或 list 容器,然后将其接口适配为栈的接口。部分源代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // stack source code (部分)  
  2. template <class _Tp,   
  3.           class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(deque<_Tp>) >  
  4. class stack {  
  5. public:  
  6.   typedef typename _Sequence::value_type      value_type;  
  7.   typedef typename _Sequence::size_type       size_type;  
  8.   typedef          _Sequence                  container_type;  
  9.   
  10.   typedef typename _Sequence::reference       reference;  
  11.   typedef typename _Sequence::const_reference const_reference;  
  12. protected:  
  13.   _Sequence c;  // 内部维护的容器, 默认 deque  
  14. public:  
  15.   stack() : c() {}  
  16.   explicit stack(const _Sequence& __s) : c(__s) {}  
  17.   
  18.   bool empty() const { return c.empty(); }           // 是否为空  
  19.   size_type size() const { return c.size(); }        // 栈的大小  
  20.   reference top() { return c.back(); }               // 访问栈顶元素  
  21.   const_reference top() const { return c.back(); }   // 访问栈顶元素(只读)  
  22.   void push(const value_type& __x) { c.push_back(__x); }  // 入栈  
  23.   void pop() { c.pop_back(); }                            // 出栈  
  24. };  

队列 queue

队列 queue 是一种先进先出(First In First Out, FIFO)的数据结构。在 STL 中,queue 底层容器默认使用 deque, 然后将其接口适配为队列的接口。部分源代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // queue source code (部分)  
  2. template <class _Tp,   
  3.           class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(deque<_Tp>) >  
  4. class queue {  
  5. public:  
  6.   typedef typename _Sequence::value_type      value_type;  
  7.   typedef typename _Sequence::size_type       size_type;  
  8.   typedef          _Sequence                  container_type;  
  9.   
  10.   typedef typename _Sequence::reference       reference;  
  11.   typedef typename _Sequence::const_reference const_reference;  
  12. protected:  
  13.   _Sequence c;   // 内部维护的容器, 默认 deque  
  14. public:  
  15.   queue() : c() {}  
  16.   explicit queue(const _Sequence& __c) : c(__c) {}  
  17.   
  18.   bool empty() const { return c.empty(); }             // 是否为空  
  19.   size_type size() const { return c.size(); }          // 队列大小  
  20.   reference front() { return c.front(); }              // 访问队首元素  
  21.   const_reference front() const { return c.front(); }  // 访问队首元素(只读)  
  22.   reference back() { return c.back(); }                // 访问队尾元素  
  23.   const_reference back() const { return c.back(); }    // 访问队尾元素(只读)  
  24.   void push(const value_type& __x) { c.push_back(__x); }   // 出队  
  25.   void pop() { c.pop_front(); }                            // 入队  
  26. };  

优先级队列 priority_queue

优先级队列 priority_queue 是一种允许用户以任意顺序将元素放入容器,但是取出元素时一定是从最高优先级的元素开始取出。默认值大的优先级高,priority_queue 默认用 vector 容器维护一个最大堆。


简单介绍一下堆,堆一般是一种隐式表述(implicit representation),简单的说堆是由另外一种容器(这里就是 vector )实现二叉堆 binary-heap 是或近似是完全二叉树,一般用数组来存储,因为其按照层序遍历正好和数组一一对应。堆分为两种:

  • 当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆
  • 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆
由于堆中的操作都基于父子节点的搜索。如果用数组的话,那么不需要额外的存储空间就可以轻松实现:
  • 左子节点标号 = 父节点标号*2+1
  • 右子节点标号 = 父节点标号*2+2
  • 父节点标号   =(子节点标号-1)/2
另外堆要求数组长度动态,所以用vector实现。部分源代码:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // priority_queue source code (部分)  
  2. template <class _Tp,   
  3.           class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(vector<_Tp>),  
  4.           class _Compare  
  5.           __STL_DEPENDENT_DEFAULT_TMPL(less<typename _Sequence::value_type>) >  
  6. class priority_queue {  
  7. public:  
  8.   typedef typename _Sequence::value_type      value_type;  
  9.   typedef typename _Sequence::size_type       size_type;  
  10.   typedef          _Sequence                  container_type;  
  11.   
  12.   typedef typename _Sequence::reference       reference;  
  13.   typedef typename _Sequence::const_reference const_reference;  
  14. protected:  
  15.   _Sequence c;      // 内部维护容器, 默认 vector  
  16.   _Compare comp;    // 优先级决策判别  
  17. public:  
  18.   priority_queue() : c() {}  
  19.   explicit priority_queue(const _Compare& __x) :  c(), comp(__x) {}   //用户可指定自己的优先级决策函数  
  20.   priority_queue(const _Compare& __x, const _Sequence& __s)   
  21.     : c(__s), comp(__x)   
  22.     { make_heap(c.begin(), c.end(), comp); }  
  23.   
  24.   bool empty() const { return c.empty(); }           // 是否为空  
  25.   size_type size() const { return c.size(); }        // 队列大小  
  26.   const_reference top() const { return c.front(); }  // 访问队首元素(只读,堆顶的元素)  
  27.   // 入队  
  28.   void push(const value_type& __x) {                  
  29.     __STL_TRY {  
  30.       c.push_back(__x);                    // 先放入 vector c 的尾端  
  31.       push_heap(c.begin(), c.end(), comp); // push_heap 泛型算法,元素先插尾端,然后上溯,复杂度为 O(logn)  
  32.     }  
  33.     __STL_UNWIND(c.clear());  
  34.   }  
  35.   // 出队  
  36.   void pop() {  
  37.     __STL_TRY {  
  38.       pop_heap(c.begin(), c.end(), comp);   
  39.       // (1) 保存 vector 尾部的值到临时变量, ;  
  40.       // (2) 将堆顶的值放在 vector 的尾部,堆顶变成空洞节点(空洞对于最大堆可理解为无穷小);  
  41.       // (3) 将堆顶的这个空洞下溯,直到移到最底层,成为叶节点;  
  42.       // (4) 将原尾部的值放入到已移到底层的空洞中;  
  43.       // (5) 对放入空洞的原尾部值在进行上溯,以维持最大堆特点;  
  44.       c.pop_back();        // 重排后,删除 vcetor 中的最后一个元素  
  45.     }  
  46.     __STL_UNWIND(c.clear());  
  47.   }  
  48. };  
【地址:http://blog.csdn.net/thisinnocence/article/details/39673043】
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值