两个栈实现一个队列
方法一:我们先来说最笨的一种方法:倒栈
大多数人的思路是:始终维护s1作为存储空间,以s2作为临时缓冲区。
入队时,将元素压入s1。
出队时,将s1的元素逐个“倒入”(弹出并压入)s2,将s2的顶元素弹出作为出队元素,之后再将s2剩下的元素逐个“倒回”s1。
见下面示意图:
不得不说,这个方法虽然可行,但真的是有点笨。。。
方法二.加了一个判断s2是否为空的过程,减少倒栈次数
入队列:直接压入元素至s1即可
出队列:如果s2不为空,把s2中的栈顶元素直接弹出。否则,把s1的所有元素全部弹出压入s2中,再弹出s2的栈顶元素
乍看没什么问题了,但其实还是有个细节要考虑的。其实无论什么方法和情况,都要考虑没有元素可供出队时的处理(2个栈都为空的时候,出队操作一定会引起异常)(细节问题)
template <typename T>
class CQueue
{
public:
CQueue(void)
{}
~CQueue(void)
{}
void appendTail(const T& node);
T deleteHead();
private:
stack<T> stack1;
stack<T> stack2;
};
template<class T>
void CQueue<T>::appendTail(const T& node)//在队列尾部添加数据
{
stack1.push(node);
}
template<class T>
T CQueue<T>::deleteHead()
{
T tmp = 0;
if (stack2.empty()) //若栈2为空
{
while (!stack1.empty())
{
tmp = stack1.top();
stack2.push(tmp);
stack1.pop();
}
}
tmp = stack2.top();
stack2.pop();
return tmp;
}
两个队列实现一个栈
入队时,谁空入谁,如果都空,则随意,假设初始入的是q1
出队时,把q1中的前size()-1个元素弹出,进入q2,弹出q1中的最后一个元素,再把q2中前size()-1个元素弹入q1,将q2中的最后一个元素出队,循环往复
如果此过程中有新元素入队,则哪个队列是空的入哪个队列。
template <typename T>
class CStack
{
public:
CStack(void)
{}
~CStack(void)
{}
void appendTail(const T& node);
T deleteHead();
private:
queue<T> q1;
queue<T> q2;
};
template<class T>
void CStack<T>::appendTail(const T& node)//在栈尾部添加数据
{
if (!q1.empty())//不为空的执行push操作
{
q1.push(node);
}
else
{
q2.push(node);
}
}
template<class T>
T CStack<T>::deleteHead()
{
int ret = 0;
if (q1.empty())
{
int i = q2.size();
while (i > 1 )//将q2队列中的数据pop到只剩一个
{
q1.push(q2.front());
q2.pop();
--i;
}
ret = q2.front();
q2.pop();
}
else
{
int i = q1.size();
while (i > 1)
{
q2.push(q1.front());
q1.pop();
--i;
}
ret = q1.front();
q1.pop();
}
return ret;
代码参考:http://blog.csdn.net/zw_1510/article/details/51927554