本篇博客主要阐释内容:
面试题: 使用两个队列模拟实现一个栈
#include<iostream>
#include<queue>
//用两个队列实现一个栈
//这道题的目的在于让我们利用队列先进先出的原则实现栈“后进先出”的原则;
//所以这里只模仿实现 push,pop,和top三个操作;
- 代码实现原理:
首先得了解队列的特点:先进先出。 既然是两个队列实现一个栈,很明显是让你通过俩个队列互相倒来倒去变成后进先出的栈!
怎么倒?
假设先放一组元素到队列q1;
q1: 1,2,3,4; //1 是队头
q2: //现在是空的!
接着需要执行Pop操作,本着后进先出的原则,肯定是要把 4 Pop掉;可是队列里的pop是每次删除一个队头元素
所以,q2就派上用场了,我们利用q2.push(q1.front())和q1.pop()交互操作把1,2,3放到q2中去;则:
q1;4;
q2;1,2,3;
这下可以pop掉4了,执行一次q1.pop();4就被删除了,此时
q1: //空;
q2:1,2,3;
假设现在要执行Push操作,我们看,这里q1是空的,那我们是不是可以直接把新元素 5 插在队列q2中:这样的话Pop的时候判断一下如果q1为空且q2不为空直接q2.pop()是不是就好了;
但是如果q1不为空,如
q1;4;
q2;1,2,3;
那就直接放如q1,要不然顺序就乱了;
现在就剩top了,这个就很简单了,如果q1不为NULL直接调用q1.back就拿到了最后一个元素,如果q1是空的
,且q2不为空,则直接q2.back(); 也就拿到了, 我在这里都忽略了两个都为空时Pop和Top的情况!
按照上面的思路就可以实现下面的代码!
*/
using namespace std;
template<typename T>
class Stack
{
public:
void Push(const T& data)
{
if(q1.size () > 0)//如果q1不为空则往q1中插入元素;
q1.push (data);
else if(q2.size () > 0)//如果q1为空q2不为空则往q2中插入元素;
q2.push (data);
else
q1.push (data);
}
void Pop()
{
if(q1.size () == 0)
{
while(q2.size() > 1)// 保证q2中有一个元素;
{
q1.push (q2.front());
q2.pop ();
}
q2.pop ();
}
else
{
if(q1.size() > 0)// 当q2为空时
{
while(q1.size () > 1)
{
q2.push (q1.front ());
q1.pop ();
}
q1.pop ();
}
}
}
T& Top()
{
if(q1.size () > 0)
{
return q1.back ();
}
else if(q2.size () > 0)
{
return q2.back ();
}
}
private:
//两个队列成员
queue<T> q1;
queue<T> q2;
};
void test()
{
Stack<int> s;
//s.Pop ();
s.Push (1);
s.Push (2);
s.Push (3);
cout<<s.Top ()<<endl;
s.Pop ();
//s.Pop();
s.Push (4);
cout<<s.Top ()<<endl;
}
int main()
{
test();
system("pause");
return 0;
}