栈和队列基础(C++版)

顺序问题

栈是先进后出

队列是先进先出

关于C++中的栈和队列

通常使用的stack是属于哪个版本的STL?

C++ 标准库有三个版本最为普遍

  1. HP STL 其他版本的C++ STL 一般是基于这个库实现的, HP STL 是C++ 第一个实现的STL源码库,并且源代码完全公开。

  2. P.J.Plauger STL 是由P.J.Plauger STL参照 HP STL实现的, 被Visual C++ 编译器所采用,并不是开源的。

  3. SGI STL 是由Silicon Graphics Computer Systems 公司参照HP STL 实现,被Linux的GCC所采用, SGI STL 是开源软件,源码可读性非常的高。

栈和队列介绍

首先, 栈的顺序是先进后出

如图所示:

 

栈会提供push 、pop 等诸多接口,所有元素必须符合先进先出,所以栈不提供走访功能,也不提供迭代功能。不像是set或者map那样有迭代器iterator可以遍历所有元素

C++中的stack是容器吗?

栈和队列是C++ 中的两个数据结构。而栈通常在C++中并不是被归类为容器,他被归类为容器适配器(container adapter)

为什么这么说呢,因为栈使用底层容器以实现其所有的工作,对外提供统一的接口,而他的底层容器是可插拔的,也就是说我们可以控制它的底层,由我们自己决定使用哪种容器来实现栈的功能。

那么问题来了,STL中的栈是使用什么实现的呢?

栈常用的底层实现可以是vector 、 queue 、 list , 都是可以实现的, 根本的原理也逃不脱链表和数组。

我们常用的SGI STL 中,如果没有自己指定底层实现的话,默认是以deque为底层缺省状态下栈的底层。

deque 是一个双向队列,只要封住一段,另一端开通,就可以实现栈的逻辑了。

SGI STL 中, 队列底层实现缺省时,也是默认以deque实现的。

我们也可以自己指定使用vector来实现栈

std::stack<int , std::vector<int> >  third

同理,队列和栈的情况是一样的。

队列同样不允许有遍历行为,不提供迭代器,实现方式也是一样的,也可以使用list来实现队列

std::queue<int , std::list<int> > third

力扣例题 : 用栈实现队列

 

思路:

首先,我们可以发现的是,使用一个栈是必然行不通的,我们需要至少两个栈来模拟队列的操作

在这里我们使用两个栈来模拟,一个作为输出栈,一个作为输入栈

push操作:

push操作相对简单,只需要直接将数据放入输入栈即可

pop操作:

pop操作相对复杂,输出栈如果为空时,需要将进栈数据全部导入,再从栈中弹出数据,如果输出栈不为空,则直接从输出栈中弹出数据。

empty操作:

当进栈和出栈都为空时,这个模拟队列自然就是个空队列了。

class MyQueue {
public:
    stack<int> InS;
    stack<int> OutS;
    MyQueue() {
​
    }
    
    void push(int x) {
        InS.push(x);
    }
    
    int pop() {
        if(OutS.empty())
            while(!InS.empty())
                {OutS.push(InS.top());
                InS.pop();}
        int result = OutS.top();
        OutS.pop();
        return result;
    }
    
    int peek() {
        int res = this -> pop();
        OutS.push(res);
        return res;
    }
    
    bool empty() {
        return InS.empty() && OutS.empty();
    }
};
​
/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

力扣例题:用队列实现栈

 

思路:

因为队列先进先出的特质与栈不同,所以它模拟栈的思路和栈模拟队列的思路又不太相同。

只需要一个队列就足以完成栈的模拟

push操作:

只需将队列数据直接放入队列即可

pop操作:

只需将除最后一个元素之外的元素重新从队头加入即可,然后将原来队尾的元素变为现在的队头再弹出。

top操作:

模拟栈的top即为queue的队尾,使用queue.back()即可

class MyStack {
public:
    queue<int> st;
    MyStack() {
​
    }
    
    void push(int x) {
        st.push(x);
    }
    
    int pop() {
        int size = st.size();
        size--;
        while(size--)
        {
            st.push(st.front());
            st.pop();
        }
        int res = st.front();
        st.pop();
        return res;
    }
    
    int top() {
        return st.back();
    }
    
    bool empty() {
        return st.empty();
    }
};
​
/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值