一、用两个栈模拟一个队列
思路:看到这个问题,首先我们应该想到的是:栈和队列各自都有什么特性。那让我们回忆一下:栈先进后出,即先入栈的后出栈,而队列是先进先出,即先入队列的先出队列。那么现在我们的目标就很明确了,用栈实现队列,即就是要用先进后出模拟出先进先出。
那么如何用栈来实现队列呐?
假设1,2,3,4,5按照顺序入栈,那么出栈的序列理应为5,4,3,2,1,出队的序列则应该为1,2,3,4,5,这时就需要借助另外一个栈,如下图:
首先栈1不空,栈2是空的,那么按照出栈的规则先将栈1中的元素出栈(5,4,3,2,1),再全部入栈到栈2中(1,2,3,4,5),此时栈顶元素就为1,然后出栈2(1,2,3,4,5),即实现了队列的出队。这样看来,栈1是作为入队的栈,而栈2是作为出队的栈。具体如下图:
看图我们就能很快写出代码来了,但是这个时候应该想一想我们的方案还有哪些不周全的地方,有哪些情况我们并没有考虑上。仔细观察,不难发现,似乎没有考虑当出队列时栈2为空的情形,实际上经过上面的思考,应该很容易发现,当想要出队列时,首先应该去看看栈2空不空,空的话就是上述方案,不空的话证明还有元素等待出队,那么直接将栈2元素出栈即可。参考代码如下:
class MyQueue
{
public:
void push(int value)
{
stack1.push(value);
}
int pop()
{
int value = 0;
if(stack2.size() <= 0)
{
while(stack1.size() > 0)
{
int tmp = stack1.top();
stack1.pop();
stack2.push(tmp);
}
}
if(stack2.size() == 0)
{
throw std::exception("empty queue");
}
value = stack2.top();
stack2.pop();
return value;
}
private:
stack<int> stack1; //入队的栈
stack<int> stack2; //出队的栈
};
总结:遇到此类问题,依然要注意逻辑上的思考,思维应该缜密。