问题描述:用两个栈实现一个队列,要求实现Push以及Pop等方法。
分析问题:栈先进后出,而队列先进先出。现有两个栈s1、s2,s1用来压入元素,s2用来弹出元素。
第一种思路是入队列时,将元素压入s1;出队列时将s1中的元素“倒”入s2中,将s2栈顶元素弹出,再“倒”回到s1。
可以优化的一点是出队列时不用将s1中的元素全部“倒”入s2中,而是在s1只剩一个元素的时候直接从s1中弹出,这样就少了一次压栈过程。
另外一种思路也是在上述基础上,入队列时,如果s1不为空,直接压入s1,否则先将s2“倒”回s1再压入s1(s2不为空);出队列时,如果s2不为空直接弹出栈顶元素,否则先将s1“倒”入s2再弹出栈顶。这样在连续出队列的情况下效率能高一些。
上述思路再优化一些:入队列直接将入队元素压入s1;出队列时如果s2不为空直接弹出栈顶元素并出队,s2为空则将s1逐个“倒入”s2(s1不为空),s1中最后一个元素弹出。不用每次都来回倒。
代码实现:
#include<iostream>
#include<stack>
using namespace std;
typedef int T;
class DoubleStack_Queue
{
public:
DoubleStack_Queue()
{}
~DoubleStack_Queue()
{}
void Push(T x)
{
s1.push(x);
}
void Pop()
{
if (!s2.empty())
{
s2.pop();
}
else
{
if (!s1.empty())
{
//将s1除最后一个元素逐个倒入s2
while (s1.size() > 1)
{
s2.push(s1.top());
s1.pop();
}
s1.pop();
}
else
{
cout << "empty" << endl;
}
}
}
bool Empty()
{
if (s1.empty() && s2.empty())
{
return true;
}
return false;
}
T& Front()
{
if (!s2.empty())
{
return s2.top();
}
if (!s1.empty())
{
while (!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
return s2.top();
}
}
T& Back()
{
if (!s1.empty())
{
return s1.top();
}
if (!s2.empty())
{
while (!s2.empty())
{
s1.push(s2.top());
s2.pop();
}
return s1.top();
}
}
void Print()
{
while (!Empty())
{
cout << Front() << ' ';
Pop();
}
}
private:
stack<T> s1;
stack<T> s2;
};
void Test()
{
DoubleStack_Queue dq;
dq.Push(1);
dq.Push(2);
dq.Push(3);
dq.Push(4);
dq.Push(5);
dq.Print();
}
int main()
{
Test();
system("pause");
return 0;
}