STL源码剖析——序列式容器#4 Stack & Queue

Stack  

  stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口,元素的新增、删除、最顶端访问都在该出口进行,没有其他位置和方法可以存取stack的元素。换言之,stack不允许有遍历行为。

 

   在学习了deque之后,我们知道了deque是一个双向开口的结构,deque的首尾端都能进行元素的插入和删除。我们既然拥有了这样的一个结构,那只要稍加调整就能符合stack的特征了,不必再另起炉灶。若以deque为底部机构并封闭其前端开口,保留尾端开口,便轻而易举地形成了一个stack。因此,SGI STL便以deque作为缺省情况下的stack底部结构,stack的实现因而非常简单,源码十分简短。

 1 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
 2 template <class T, class Sequence = deque<T> >
 3 #else
 4 template <class T, class Sequence>
 5 #endif
 6 class stack {
 7     //以下 __STL_NULL_TMPL_ARGS会展开为<>,是来自别处的typedef
 8     friend bool operator== __STL_NULL_TMPL_ARGS(const stack&, const stack&);
 9     friend bool operator< __STL_NULL_TMPL_ARGS(const stack&, const stack&);
10 public:
11     //与deque别无二致的相应类型
12     typedef typename Sequence::value_type value_type;
13     typedef typename Sequence::size_type size_type;
14     typedef typename Sequence::reference reference;
15     typedef typename Sequence::const_reference const_reference;
16 protected:
17     Sequence c;    // 底层容器,缺省为deque<T>
18 public:
19     // 以下完全利用 Sequence c 的操作,完成 stack 的操作。
20     bool empty() const { return c.empty(); }
21     size_type size() const { return c.size(); }
22     reference top() { return c.back(); }
23     const_reference top() const { return c.back(); }
24     // deque 是两头可进出,stack 是末端进,末端出(所以后进者先出)。
25     void push(const value_type& x) { c.push_back(x); }
26     void pop() { c.pop_back(); }
27 };
28 
29 template <class T, class Sequence>
30 bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
31     return x.c == y.c;
32 }
33 
34 template <class T, class Sequence>
35 bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
36     return x.c < y.c;
37 }
38 
39 __STL_END_NAMESPACE
40 
41 #endif /* __SGI_STL_INTERNAL_STACK_H */

  另注,stack没有迭代器,因为stack的所有元素必须符合“先进后出”的条件,只有stack最顶端的元素,才有被机会访问或弹出。所以stack不提供遍历功能,也不提供迭代器。

 

Queue

  与之相反,有先进后出的数据结构,肯定也会有先进先出的数据结构,queue就是一种先进先出的数据结构。它有一个入口、一个出口,允许从最底端加入元素,从最顶端弹出元素,除了这两个存取操作外,没有任何其他方法可以存取queue的其他元素。同样,它不允许有遍历行为。

 

   我们只要取deque的部分功能便可实现queue的全部。所以queue的实现非常简单,源码十分简短:

 1 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
 2 template <class T, class Sequence = deque<T> >
 3 #else
 4 template <class T, class Sequence>
 5 #endif
 6 class queue {
 7     friend bool operator== __STL_NULL_TMPL_ARGS(const queue& x, const queue& y);
 8     friend bool operator< __STL_NULL_TMPL_ARGS(const queue& x, const queue& y);
 9 public:
10     typedef typename Sequence::value_type value_type;
11     typedef typename Sequence::size_type size_type;
12     typedef typename Sequence::reference reference;
13     typedef typename Sequence::const_reference const_reference;
14 protected:
15     Sequence c; // 底层容器
16 public:
17     // 以下完全利用 Sequence c 的操作,完成 queue 的操作。
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     // deque 是两头可进出,queue 是末端进,前端出(所以先进先出)。
25     void push(const value_type& x) { c.push_back(x); }
26     void pop() { c.pop_front(); }
27 };
28 template <class T, class Sequence>
29 bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y)
30 {
31     return x.c == y.c;
32 }
33 template <class T, class Sequence>
34 bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y)
35 {
36     return x.c < y.c;
37 }

  同样,queue不提供迭代器。

posted @ 2019-11-03 16:36  羽园原华  阅读(151)  评论(0编辑  收藏  举报