两个栈实现一个队列(逻辑推理过程+代码)

1 篇文章 0 订阅
1 篇文章 0 订阅

首先先看目的:
队列——先进先出或者叫后进后出
手里有的资源:
两个队列——先进后出,后进先出。
方法:
后进先出(栈)+先进后出(另一个栈)=后进后出(队列)
步骤: 把第一个栈叫做栈A,第二个栈叫做栈B。
进队列(进栈A):入A
出队列:

  • B非空,出B
  • B空,把A全部倒进来B再出B

思考:

  • 因为必须需要第二个栈来将顺序倒过来,所以出队列最后都是从B出,这是毋庸置疑的
  • 既然要出,那么出的就是最先进来的那个元素,如果B里面有,显然B最上面(曾经是A最下面那个)就是最先进来的。
  • 如果B里面是空的,那么就把A里面的全部倒进来再开始出。为什么要全部,因为要把A最下面那个给倒腾出来,既然在最下面压着,所以必须把所有的都倒腾进来B才能把最下面的给整到B最上面
    代码如下:

```cpp
#include <iostream>
#include <queue>
#include <exception>

template<class T> class MyStack {
 public:
     void push(const T& num);
     T pop();
     T top();
     void swapQueue();// 交换dataQueue和helpQueue
 private:
    std::queue<T> dataQueue;    // 数据队列
    std::queue<T> helpQueue;    // 帮助队列
};
template<typename T>
void MyStack<T>::swapQueue() {
    std::queue<T> tmp = dataQueue;
    dataQueue = helpQueue;
    helpQueue = tmp;
}
template<typename T>
void MyStack<T>::push(const T& num) {   // 不管是上面情况,送入数据都是放到dataQueue里面
    dataQueue.push(num);
}
template<typename T>
T MyStack<T>::pop() {
    if (dataQueue.empty()) {
        throw std::runtime_error("queue is empty");
    } else {
        while (dataQueue.size() > 1) {  // 当dataQueue
            helpQueue.push(dataQueue.front());
            dataQueue.pop();
        }
        T res = dataQueue.front();    // 这个dataQueue的最后元素也就是stack的栈顶元素
        dataQueue.pop();    // dataQueue已经为空,helpQueue存放n-1个数
        swapQueue();   // 交换二个队列
        return res;
    }
}
template<typename T>
T MyStack<T>::top() {
    if (dataQueue.empty()) {
        throw std::runtime_error("queue is empty");
    } else {
        while (dataQueue.size() > 1) {  // 当dataQueue
            T data = dataQueue.front();
            dataQueue.pop();
            helpQueue.push(data);
        }
        T res = dataQueue.front();    // 这个dataQueue的最后元素也就是stack的栈顶元素
        dataQueue.pop();    // 此时dataQueue已经为空,helpQueue存放n-1个数
        helpQueue.push(res);    // 获取top元素需要将原来数据返回
        swapQueue();
        return res;
    }
}

int main() {
    MyStack<int> s;
	s.push(4);
	s.push(6);
	s.push(3);
	s.push(1);
	std::cout << s.pop() << std::endl;
	std::cout << s.pop() << std::endl;
    s.push(5);
	std::cout << s.pop() << std::endl;
	std::cout << s.pop() << std::endl;

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值