代码随想录Day 10 || 232用栈实现队列 、225用队列实现栈

232用栈实现队列

栈的特点是后进先出,而队列的特点是先进先出。我们使用两个栈来模拟队列的先进先出特点。
假设我们先往队列中依次加入1、2、3这三个元素(即执行三次push操作),在执行peek操作,按照队列的特点peek操作得到的应该是1,但是在栈中我们通过top得到的是3,我们再用另一个栈将元素的顺序逆转一下,如图所示:

每次在push操作时,我们把要加入队列的元素先加入inStack中;当要执行peek操作或者pop操作时,如果outStack栈中不为空,直接对outStack栈进行top操作或者pop操作;如果outStack栈为空,先把inStack栈中的元素全部弹入到outStack栈中,再对outStack栈进行top操作或者pop操作 【这里为什么要先判断outStack是否为空? outStack栈中已有元素的顺序永远在inStack栈中元素的前面

以下为可运行代码:

class MyQueue {
public:
    MyQueue() {

    }
    
    void push(int x) {
        inStack.push(x);
    }
    
    int pop() {
        //如果出栈为空
        if(outStack.empty()){
            while(!inStack.empty()){
                outStack.push(inStack.top());
                inStack.pop();
            }
        }
        int result = outStack.top();
        outStack.pop();
        return result;
    }
    
    int peek() {
        // 这里直接复用已经实现的pop操作,但是pop函数里弹出了栈顶元素,这里要把弹出的元素再加入到outStack中
        int result = this->pop();
        outStack.push(result);
        return result;
    }
    
    bool empty() {
        if(inStack.empty() && outStack.empty()){
            return true;
        }
        return false;

    }
private:
    stack<int> inStack, outStack;
};

225用队列实现栈

可以用一个队列也可以用两个队列来实现栈

方法一:使用一个队列

用一个队列时,只要循环操作就可以实现栈的功能,如图:
在这里插入图片描述
我们先依次弹入三个元素1、2、3,在执行top操作时,我们想得到的是元素3,这时只要把元素3前面已有的元素从队列中以此弹出并重新加入队列中即可。
代码如下:

class MyStack {
public:
    MyStack() {
    }
    
    void push(int x) {
        queue1.push(x);
    }
    
    int pop() {
        int size = queue1.size();
        for(int i = 0; i < size - 1; i++){
            int temp = queue1.front();
            queue1.pop();
            queue1.push(temp);
        }
        int result = queue1.front();
        queue1.pop();
        return result;
    }
    
    int top() {
        return queue1.back();
    }
    
    bool empty() {
        if(queue1.empty()){
            return true;
        }
        return false;
    }
private:
    queue<int> queue1;
};

方法二:使用两个队列

用两个队列也可以实现,和用两个栈实现队列方法的不同,这两个队列需要进行交换操作,代码如下:

class MyStack {
public:
    MyStack() {
    }
    
    void push(int x) {
        queue1.push(x);
    }
    
    int pop() {
        int result = 0;
        // 这一段代码其实就相当于把循环的元素另外写入到备用的queue2中,而不是像方法一那样重新再加入到queue1中
        while(!queue1.empty()){
            result = queue1.front();
            queue1.pop();
            if(!(queue1.empty())){
                queue2.push(result);
            }
        }
        //将queue2中的值重新赋给queue1,并将queue2清零
        queue1 = queue2;
        while(!queue2.empty()){
            queue2.pop();
        }
        return result;
    }
    
    int top() {
        return queue1.back();
    }
    
    bool empty() {
        if(queue1.empty() && queue2.empty()){
            return true;
        }
        return false;
    }
private:
    queue<int> queue1, queue2;
};

方法一和方法二的主要区别在于,图示中浅蓝色的1、2两个元素是直接加入到原本队列里,还是再用一个新的queue2来保存。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值