【从零开始】不可分割的栈和队列

栈和队列是非常经典的数据结构,基本上是随处可见了。

为什么把这两者放在一起说呢?

因为对于C++的STL来说,这两者都是容器适配器,默认都是以deque为底层实现的。

我们都知道栈是【先进后出】,队列是【先进先出】

使用双端队列deque并且进行一些加工就可以实现栈和队列的效果,这也是STL中栈和队列的实现方式。

具体细节可以看这篇笔记:
【STL源码剖析】总结笔记(7):巧妙的deque


栈和队列互相实现

有一类题目是栈和队列的相互实现,比如用栈实现队列或者用队列实现栈。

虽然没有太明显的实际意义,但是对于理解栈和队列的结构至关重要。

用栈实现队列

leetcode 232 用栈实现队列

用栈实现队列就要思考队列的特点,那些是栈需要调整的。

入队列和入栈一致,不需要修改。

而出队和出栈恰好相反,所以我们需要两个栈来对栈内的数据进行处理。

比如想实现1,2,3入队列然后1出队。

这时候要把1号栈中的[1,2,3]全部出栈,再放入2号栈变为[3,2,1],这时出栈的就是队头。

如果1出队后,变为[2,3],此时[4,5]又入栈了怎么办呢?

这就要看2号栈里是否还有数据,如果有那么还是存在队头的,不需要把新数据倒入。

class MyQueue {
public:
    stack<int>stack1;
    stack<int>stack2;
    MyQueue() {

    }
    
    void push(int x) {
        stack1.push(x);

    }
    
    int pop() {
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.top());
                stack1.pop();
            }

        }
        int res=stack2.top();
        stack2.pop();
        return res;

    }
    
    int peek() {
        int res=pop();//直接复用pop()
        stack2.push(res);
        return res;

    }
    
    bool empty() {
        return stack1.empty()&&stack2.empty();

    }
};

需要注意:

在stack中的pop()会直接把栈顶元素删除,而不会返回值。所以想要实现题目中的pop()需要先记录再pop()

peek()这个地方直接复用了写好的pop()函数,因为需要队列的头元素,所以复用更高效。

用队列实现栈

leetcode 225 用队列实现栈

队列实现栈就要考虑栈的特点和队列有什么差异。

队列入队和栈入栈还是一致的,不需要改动。

出队因为是队头,而栈需要出的元素在队尾,所以需要调整。

这里我们不使用新的空间,直接把前面的元素搬到队尾的后面,再次入队。

比如[1,2,3,4],弹出栈头应该是4,我们把前面的元素重新入队,得到[4,1,2,3],再弹出4即可。

class MyStack {
public:
    queue<int>que;
    MyStack() {

    }
    
    void push(int x) {
        que.push(x);

    }
    
    int pop() {
        int size=que.size();
        while(size>1){
            que.push(que.front());
            que.pop();
            size--;
        }
       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值