两个栈实现一个队列,两个队列实现一个栈

这篇博客详细介绍了如何使用两个栈实现一个队列,以及用栈实现队列的方法,强调了队列的先入先出特性。同时,还探讨了队列实现栈的策略,通过队列的特性实现后入先出的效果。最后,列举了STL中栈和队列的主要接口函数。这些实现和接口对于理解和运用数据结构在实际编程中至关重要。
摘要由CSDN通过智能技术生成

1. 两个栈实现一个队列

这两道题并没有考察太多的算法,就是单纯对队列和栈特性的应用。
细节还是挺多需要注意的。

题目链接

一个栈是无法完成队列操作的,我们要时刻记住队列的性质,先入先出。
入队列,我们可以按入栈进行操作,那么出队列呢,由于出队列是出队头的数据,我们不可能动栈底的数据,所以自然不能用一个栈。
在这里插入图片描述
所以我们用两个栈,一个栈用来入队列,一个栈用于出队列

  //第一个栈用于入队列,第二个栈用于出队列
    stack<int>stack1,stack2;

然后构造函数初始化

CQueue() {
     while(!stack1.empty())
     {
           stack1.pop();
     }
     while(!stack2.empty())
     {
         stack2.pop();
     }
    }

入队列与入栈无差别

 void appendTail(int value) {
        stack1.push(value);
    }
    

出队列需要先把在第一个栈里的数据放进第二个栈里。(因为我们要出栈底的数据不能直接出需要导入第二个栈,在第一个栈里是栈底,在第二个栈里是栈顶,然后出栈)就完成了出队列,符合先入先出
在这里插入图片描述

 //第二个栈为空,才进行入第二个栈
        if(stack2.empty())
        {
        while(!stack1.empty())
        {
            stack2.push(stack1.top());
            stack1.pop();
        }
        }
        //第二个栈不为空,返回栈顶数据
        if(!stack2.empty())
        {
             int deleteNums=stack2.top();
             stack2.pop();
             return deleteNums;
        }

那么为什么第二个栈为空,才进行新一轮的把第一个栈的数据往它里面进行导入呢。因为我一开始没有对第二个栈为空进行判断,导致逻辑出错。

原本应该是第二个栈为空才进行新一轮数据的导入,由于第二次模拟出队列我一开始没有对第二个栈进行判空,1刚出第二个栈,又把5导入了进来,正确的做法应该是等第二个栈里的数据全部出去,再倒入新的数据
在这里插入图片描述

完整代码

class CQueue {
    //第一个栈用于入队列,第二个栈用于出队列
    stack<int>stack1,stack2;
public:
    CQueue() {
     while(!stack1.empty())
     {
           stack1.pop();
     }
     while(!stack2.empty())
     {
         stack2.pop();
     }
    }
    
    void appendTail(int value) {
        stack1.push(value);
    }
    
    int deleteHead() {
        //第二个栈为空,才进行入第二个栈
        if(stack2.empty())
        {
        while(!stack1.empty())
        {
            stack2.push(stack1.top());
            stack1.pop();
        }
        }
        //第二个栈不为空,返回栈顶数据
        if(!stack2.empty())
        {
             int deleteNums=stack2.top();
             stack2.pop();
             return deleteNums;
        }
        else
        {
            return -1;
        }
    }
};

2. 用栈实现队列

题目链接

和上面的题逻辑一样,不过这道题函数接口完整一点。
无论是pop(出队列),还是peak(返回队头元素)
都需要检查当stack2为空时,把stack1的元素放进stack2。对stack2进行操作,所以其实可以把这段逻辑写成接口,不过太麻烦了,直接复制了,工程中注意代码复用性写成函数封装起来就好了。

完整代码

class MyQueue {
    stack<int>stack1,stack2;
public:
    /** Initialize your data structure here. */
    MyQueue() {
     
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
            stack1.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        if(stack2.empty())
        {
        while(!stack1.empty())
        {
            stack2.push(stack1.top());
            stack1.pop();
        }
        }
      
        int removeNums=stack2.top();
        stack2.pop();
        return removeNums;
     

    }
    
    /** Get the front element. */
    int peek() {
        //栈2为空,把栈1的数据放进栈2里,用于出队列
         if(stack2.empty())
        {
        while(!stack1.empty())
        {
            stack2.push(stack1.top());
            stack1.pop();
        }
        }

        //栈顶,相当于队头
        return stack2.top();
  
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
           return stack1.empty()&&stack2.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();
 */

3. 队列实现栈

题目链接

开始就和上面一样想用两个队列实现,一个输入,一个输出,最后发现没啥用。因为你只能对队头进行操作。(像下图一样,出栈要的是4,你是队列只能对队头操作,只能拿到1,所以一个队列输入,一个队列输出是不行的。)
在这里插入图片描述
换一种思路,实现栈,无非就是先进后出,像上图,要想出4,我们让另一个队列暂时把除了最后一个之外的元素保存起来。然后pop掉q1的最后一个元素。q1清空
在这里插入图片描述
q1pop完成,符合栈的后入先出。那么接下来呢?还有其他数据。
交换两个队列(q2赋值给为空的q1,清空q2),使用前面相同的逻辑(另一个队列保存除了最后一个元素之外的数据,这个队列pop掉这个数据)
4 3 2 1就完成了先进后出。
在这里插入图片描述依次迭代即可

完整代码

class MyStack {
    queue<int>queue1,queue2;
public:
    /** Initialize your data structure here. */
    MyStack() {

    }
    
    /** Push element x onto stack. */
    void push(int x) {
            queue1.push(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int n=queue1.size()-1;
        while(n)
        {
            int ret=queue1.front();
            queue2.push(ret);
            queue1.pop();
            n--;
        }
        int stackTop=queue1.front();
        queue1.pop();
        //交换两个队列
        // 相当于swap(queue1,queue2);
        queue1=queue2;
        //赋值给queue1后,清空queue2
        while(!queue2.empty())
        {
            queue2.pop();
        }
        
        return stackTop;
    }
    
    /** Get the top element. */
    int top() {
           return queue1.back();
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {

            return queue1.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();
 */

4. STL中栈的接口

empty()//如果栈为空返回true,否则返回false

size()//返回栈中元素的个数

pop()//删除栈顶元素但不返回其值

top()//返回栈顶的元素,但不删除该元素

push(X)//在栈顶压入新元素 ,参数X为要压入的元素

5. STL中队列的接口

push(x) 将x压入队列的末端

pop() 弹出队列的第一个元素(队顶元素),注意此函数并不返回任何值

front() 返回第一个元素(队顶元素)

back() 返回最后被压入的元素(队尾元素)

empty() 当队列为空时,返回true

size() 返回队列的长度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值