STL之stack 和 queue

Posted randyniu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL之stack 和 queue相关的知识,希望对你有一定的参考价值。

这两种容器在STL中被称为是适配器,是对deque的一种限制容器,操作仅仅可以在头部或者是尾部进行。

STL中的stack默认是用deque来实现的,但是我觉得用list实现第更高效一点,简单的slist就可以这样做。

当然也可以使用vector来进行实现,不过vector的生长确实是要考虑的范畴,因此觉得单纯的stack用单向列表进行实现就很好了。

template <class _Tp, class _Sequence>
class stack {

  // requirements:

  __STL_CLASS_REQUIRES(_Tp, _Assignable);
  __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence);
  typedef typename _Sequence::value_type _Sequence_value_type;
  __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);


#ifdef __STL_MEMBER_TEMPLATES
  template <class _Tp1, class _Seq1>
  friend bool operator== (const stack<_Tp1, _Seq1>&,
                          const stack<_Tp1, _Seq1>&);
  template <class _Tp1, class _Seq1>
  friend bool operator< (const stack<_Tp1, _Seq1>&,
                         const stack<_Tp1, _Seq1>&);
#else /* __STL_MEMBER_TEMPLATES */
  friend bool __STD_QUALIFIER
  operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&);
  friend bool __STD_QUALIFIER
  operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&);
#endif /* __STL_MEMBER_TEMPLATES */

public:
    // 由于stack仅支持对栈顶元素的操作, 所以不定义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;//底层容器类型,默认为deque容器
public:
    //下面对stack的维护完全依赖于底层容器的操作
  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(); }
};
template <class _Tp, class _Sequence>
class stack {

  // requirements:

  __STL_CLASS_REQUIRES(_Tp, _Assignable);
  __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence);
  typedef typename _Sequence::value_type _Sequence_value_type;
  __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);


#ifdef __STL_MEMBER_TEMPLATES
  template <class _Tp1, class _Seq1>
  friend bool operator== (const stack<_Tp1, _Seq1>&,
                          const stack<_Tp1, _Seq1>&);
  template <class _Tp1, class _Seq1>
  friend bool operator< (const stack<_Tp1, _Seq1>&,
                         const stack<_Tp1, _Seq1>&);
#else /* __STL_MEMBER_TEMPLATES */
  friend bool __STD_QUALIFIER
  operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&);
  friend bool __STD_QUALIFIER
  operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&);
#endif /* __STL_MEMBER_TEMPLATES */

public:
    // 由于stack仅支持对栈顶元素的操作, 所以不定义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;//底层容器类型,默认为deque容器
public:
    //下面对stack的维护完全依赖于底层容器的操作
  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(); }
};
template <class _Tp, class _Sequence>
class stack {

  // requirements:

  __STL_CLASS_REQUIRES(_Tp, _Assignable);
  __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence);
  typedef typename _Sequence::value_type _Sequence_value_type;
  __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);


#ifdef __STL_MEMBER_TEMPLATES
  template <class _Tp1, class _Seq1>
  friend bool operator== (const stack<_Tp1, _Seq1>&,
                          const stack<_Tp1, _Seq1>&);
  template <class _Tp1, class _Seq1>
  friend bool operator< (const stack<_Tp1, _Seq1>&,
                         const stack<_Tp1, _Seq1>&);
#else /* __STL_MEMBER_TEMPLATES */
  friend bool __STD_QUALIFIER
  operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&);
  friend bool __STD_QUALIFIER
  operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&);
#endif /* __STL_MEMBER_TEMPLATES */

public:
    // 由于stack仅支持对栈顶元素的操作, 所以不定义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;//底层容器类型,默认为deque容器
public:
    //下面对stack的维护完全依赖于底层容器的操作
  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(); }
};

又想说C++中模板类的强大了。真是牛逼的思想。

queue和stack一样,也是受限制操作的容器。

template <class _Tp, class _Sequence>
class queue {

  // requirements:

  __STL_CLASS_REQUIRES(_Tp, _Assignable);
  __STL_CLASS_REQUIRES(_Sequence, _FrontInsertionSequence);
  __STL_CLASS_REQUIRES(_Sequence, _BackInsertionSequence);
  typedef typename _Sequence::value_type _Sequence_value_type;
  __STL_CLASS_REQUIRES_SAME_TYPE(_Tp, _Sequence_value_type);


#ifdef __STL_MEMBER_TEMPLATES 
  template <class _Tp1, class _Seq1>
  friend bool operator== (const queue<_Tp1, _Seq1>&,
                          const queue<_Tp1, _Seq1>&);
  template <class _Tp1, class _Seq1>
  friend bool operator< (const queue<_Tp1, _Seq1>&,
                         const queue<_Tp1, _Seq1>&);
#else /* __STL_MEMBER_TEMPLATES */
  friend bool __STD_QUALIFIER
  operator== __STL_NULL_TMPL_ARGS (const queue&, const queue&);
  friend bool __STD_QUALIFIER
  operator<  __STL_NULL_TMPL_ARGS (const queue&, const queue&);
#endif /* __STL_MEMBER_TEMPLATES */

public:
    // 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;//底层容器,默认为deque容器,用户可自行指定容器类型
public:
    //下面对queue的维护完全依赖于底层容器的操作 
  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(); }
};

queue也可以使用双向循环列表来实现,也就是STL中的list来实现。

在刷题的时候这两中数据结构用的还是挺多的。

 

以上是关于STL之stack 和 queue的主要内容,如果未能解决你的问题,请参考以下文章

6-5-1:STL之stack和queue——stack和queue的快速入门常用接口以及适配器的概念

C++STL之stack和queue以及deque详解

C++STL之stack和queue以及deque详解

带你深入理解STL之Stack和Queue

6-5-2:STL之stack和queue——双端队列deque

STL容器适配器stack和queue