STL源码剖析 stack 栈 概述->(使用deque双端队列 / list链表)作为stack的底层容器

本文介绍了如何使用C++ STL中的deque实现Stack数据结构,重点讲解了Stack的构造原理、基本操作以及为何Stack不提供遍历。通过deque的头部封闭来实现先进后出特性,并讨论了Stack作为containeradapter的概念。实例演示了基于list的Stack应用,以及相关函数如empty(), size(), top(), push_back(), pop_back()的使用。
  • Stack是一种先进后出的数据结构,他只有一个出口
  • stack允许 新增元素、移除元素、取得最顶端的元素,但是无法获得stack的内部数据,因此satck没有遍历行为

 Stack定义的完整列表 (双端队列作为Stack的底层容器)

  • 将deque作为Stack的底部结构,对其原有的接口进行适配,使其满足"先进后出"的特性
  • deque是双向开口的数据结构,只需要封闭deque的头端开口(缺省实现),便轻而易举的形成了一个stack。
  • Stack基于deque,这种“修改某物的接口 形成另外一种事物的”的性质归结为 adapter (配接器),因此将stack不归类为容器,而将其归结为 container adapter (容器适配器)
  • 先前自己写的 STL版的 deque 缺失的代码比较多,因此下面的代码中 class Sequence = std::deque<T> 借用STL标准库的deque实现
//定义在stl_config.h文件中
//但是没有找到 具体详情参见 参考链接
# ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS
# define __STL_NULL_TMPL_ARGS <>
# else
# define __STL_NULL_TMPL_ARGS
# endif

template <class T,class Sequence = std::deque<T>>
class stack{
    //__STL_NULL_TMPL_ARGS会展开为 <> 
    friend bool operator== __STL_NULL_TMPL_ARGS(const stack&,const stack&);
    friend bool operator< __STL_NULL_TMPL_ARGS(const stack&,const stack&);
public:
    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:
    //底层容器
    Sequence c;
public:
    //以下完全使用Sequence c的操作,完成stack的操作
    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();}
    //deque 是两头可以进出,stack是末端进,末端出 (所以后进者先出)
    void push(const value_type& x){ c.push_back(x);}
    void pop(){return c.pop_back();}
};
    
template <class T,class Sequence>
bool operator==(const stack<T,Sequence>&x,const stack<T,Sequence>&y){
    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的顶端的元素才会被外界取用,因此 stack不需要提供遍历元素的迭代器

基于底层容器链表list的Stack

  • Stack需要的函数如 empty、size()、back、push_back、pop_back是链表也支持的
  • 使用范例
#include <stack>
#include <list>
#include <iostream>
#include <algorithm>

int main(){
    std::stack<int,std::list<int>>list_stack;
    list_stack.push(1);
    list_stack.push(3);
    list_stack.push(5);
    list_stack.push(7);

    std::cout << list_stack.size() << std::endl; //4
    std::cout << list_stack.top() << std::endl;  //7

    list_stack.pop();
    std::cout << list_stack.top() << std::endl; //5
    list_stack.pop();
    std::cout << list_stack.top() << std::endl; //3
    list_stack.pop();
    std::cout << list_stack.top() << std::endl; //1

    std::cout << list_stack.size() << std::endl; //1
}

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值