SGISTL源码阅读十七 stack(栈)

SGISTL源码阅读十七 stack(栈)

前言

前面我们已经学习了序列式容器vectorlistdeque
本次要进行分析的是stack,它是一种先进后出(First In Lat Out,FILO)数据结构,在学习数据结构的时候应该都接触过,在这里stack是一个配接器(adapter),它默认以deque容器作为它的底部结构实现。接下来我们深入源码进行学习。

  • 配接器
    具有这种“修改某物接口,形成另一种风貌”之性质者,称为adapter

深入源码

stack的定义部分

#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
//使用了deque作为它的底层
template <class T, class Sequence = deque<T> >
#else
//也可指定
template <class T, class Sequence>
#endif
class stack {
  //操作符重载,友元函数声明
  friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&);
  friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&);
public:
  //声明了相应型别
  //但是我们可以注意到这里只有4个,stack是没有迭代器的
  typedef typename Sequence::value_type value_type;
  typedef typename Sequence::size_type size_type;
  typedef typename Sequence::reference reference;
  typedef typename Sequence::const_reference const_reference;
protected:
  //默认使用了deque作为底层容器
  Sequence c;

通过以上源码我们发现stack并没有迭代器,但是这一点并不难理解。所有进入stack的元素都必须满足FILO,它并不提供遍历或是其他访问操作,只能从stack的顶端pop出元素或者通过top获取顶部的元素。

stack操作符重载

//重载==
template <class T, class Sequence>
bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
  //底层的Sequence相等则两个stack相等
  return x.c == y.c;
}
//重载<,思想类似重载==
template <class T, class Sequence>
bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
  return x.c < y.c;
}

stack提供的接口

stack所提供的接口也是完全利用了底层容器c来完成操作

public:
  //判断stack是否为空
  bool empty() const { return c.empty(); }
  //获取stack的长度
  size_type size() const { return c.size(); }
  //获取stack的顶部元素
  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(); }

stack的简单使用

从源码可以看出,stack缺省使用deque作为它的底层容器,但是也可以指定底层容器。

#include <iostream>
#include <stack>
using namespace std;

int main()
{
	//缺省使用deque作为底层容器
	stack<int> mystack;
    mystack.push(6);
    mystack.push(2);
    mystack.push(5);
    mystack.push(0);

    cout << "size:" << mystack.size() << endl;
    cout << "top element:" << mystack.top() << endl;

    mystack.pop();
    cout << "top element:" << mystack.top() << endl;
    mystack.pop();
    cout << "top element:" << mystack.top() << endl;
    mystack.pop();
    cout << "top element:" << mystack.top() << endl;
    mystack.pop();
    cout << "size:" << mystack.size() << endl;
    return 0;
}
#include <iostream>
#include <stack>
#include <vector>
using namespace std;

int main()
{
    //stack<int> mystack;
    //指定vector作为底层容器
    stack<int, vector<int> > mystack;
    mystack.push(6);
    mystack.push(2);
    mystack.push(5);
    mystack.push(0);

    cout << "size:" << mystack.size() << endl;
    cout << "top element:" << mystack.top() << endl;

    mystack.pop();
    cout << "top element:" << mystack.top() << endl;
    mystack.pop();
    cout << "top element:" << mystack.top() << endl;
    mystack.pop();
    cout << "top element:" << mystack.top() << endl;
    mystack.pop();
    cout << "size:" << mystack.size() << endl;
    return 0;
}

在这里插入图片描述

总结

在阅读STL源码之前对stack可能的数据结构已经比较清楚了,因为它是最最基础的一个数据结构了。之前也自己实现过stack,底层无非使用到了数组和链表。
阅读了STL源码发现它只是一个配接器,通过调用比它更加底层的容器来进行操作,代码也非常地简单。
我们常把另外一个数据结构和stack作比较,那就是queue,一种FIFO的数据结构,我们将在下一篇文章中分析它。

猜你喜欢

转载自blog.csdn.net/lyn_00/article/details/84062217
今日推荐