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

来源:互联网 发布:小甲鱼c语言视频下载 编辑:程序博客网 时间:2024/05/02 14:47

栈 stack 

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

// stack source code (部分)template <class _Tp,           class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(deque<_Tp>) >class stack {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;  // 内部维护的容器, 默认 dequepublic:  stack() : c() {}  explicit stack(const _Sequence& __s) : c(__s) {}  bool empty() const { return c.empty(); }           // 是否为空  size_type size() const { return c.size(); }        // 栈的大小  reference top() { return c.back(); }               // 访问栈顶元素  const_reference top() const { return c.back(); }   // 访问栈顶元素(只读)  void push(const value_type& __x) { c.push_back(__x); }  // 入栈  void pop() { c.pop_back(); }                            // 出栈};

队列 queue

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

// queue source code (部分)template <class _Tp,           class _Sequence __STL_DEPENDENT_DEFAULT_TMPL(deque<_Tp>) >class 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;   // 内部维护的容器, 默认 dequepublic:  queue() : c() {}  explicit queue(const _Sequence& __c) : c(__c) {}  bool empty() const { return c.empty(); }             // 是否为空  size_type size() const { return c.size(); }          // 队列大小  reference front() { return c.front(); }              // 访问队首元素  const_reference front() const { return c.front(); }  // 访问队首元素(只读)  reference back() { return c.back(); }                // 访问队尾元素  const_reference back() const { return c.back(); }    // 访问队尾元素(只读)  void push(const value_type& __x) { c.push_back(__x); }   // 出队  void pop() { c.pop_front(); }                            // 入队};

优先级队列 priority_queue

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


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

  • 当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆
  • 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆
由于堆中的操作都基于父子节点的搜索。如果用数组的话,那么不需要额外的存储空间就可以轻松实现:
  • 左子节点标号 = 父节点标号*2+1
  • 右子节点标号 = 父节点标号*2+2
  • 父节点标号   =(子节点标号-1)/2
另外堆要求数组长度动态,所以用vector实现。部分源代码:
// priority_queue source code (部分)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;      // 内部维护容器, 默认 vector  _Compare comp;    // 优先级决策判别public:  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); }  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 c 的尾端      push_heap(c.begin(), c.end(), comp); // push_heap 泛型算法,元素先插尾端,然后上溯,复杂度为 O(logn)    }    __STL_UNWIND(c.clear());  }  // 出队  void pop() {    __STL_TRY {      pop_heap(c.begin(), c.end(), comp);       // (1) 保存 vector 尾部的值到临时变量, ;      // (2) 将堆顶的值放在 vector 的尾部,堆顶变成空洞节点(空洞对于最大堆可理解为无穷小);      // (3) 将堆顶的这个空洞下溯,直到移到最底层,成为叶节点;      // (4) 将原尾部的值放入到已移到底层的空洞中;      // (5) 对放入空洞的原尾部值在进行上溯,以维持最大堆特点;      c.pop_back();        // 重排后,删除 vcetor 中的最后一个元素    }    __STL_UNWIND(c.clear());  }};
【地址:http://blog.csdn.net/thisinnocence/article/details/39673043】

1 0
原创粉丝点击