使用两个栈实现一个队列
始终维护s1作为存储空间,以s2作为临时缓冲区。
入队时,将元素压入s1。
出队时,将s1的元素逐个“倒入”(弹出并压入)s2,将s2的顶元素弹出作为出队元素,之后再将s2剩下的元素逐个“倒回”s1。
如图:(在下图的方法中做出优化)
优化
入队时,将元素压入s1。
出队时,判断s2是否为空,如不为空,则直接弹出顶元素;如为空,则将s1的元素逐个“倒入”s2,把最后一个元素弹出并出队。
这个思路,避免了反复“倒”栈,仅在需要时才“倒”一次。
注意:
要考虑没有元素可供出队时的处理(2个栈都为空的时候,出队操作一定会引起异常)。在实际写代码时,忽略这些判断或异常处理,程序会出现问题。
实现代码:
#include <stack>
template <class T>
class Queue
{
public:
Queue(void)
{}
~Queue(void)
{}
void Push_Tail(const T& p);
T DeleteHead();
private:
stack<T> s1;
stack<T> s2;
};
template <class T>
//在队列尾部添加数据
void Queue<T>::Push_Tail(const T& p)
{
s1.push(p);
}
template <class T>
T Queue<T>::DeleteHead()
{
T tmp = 0;
//若栈2为空
if (s2.empty())
{
while (!s1.empty())
{
tmp = s1.top();
s2.push(tmp);
s1.pop();
}
}
tmp = s2.top();
s2.pop();
return tmp;
}
测试代码:
#include <iostream>
using namespace std;
#include "Queue.h"
int main()
{
Queue<int> q1;
q1.Push_Tail(1);
int ret = q1.DeleteHead();
cout << ret << endl;
system("pause");
return 0;
}
使用两个队列实现一个栈
q1是专职进出栈的,q2只是个中转站
入栈:直接入队列q1即可
出栈:把q1的除最后一个元素外全部转移到队q2中,然后把刚才剩下q1中的那个元素出队列。之后把q2中的全部元素转移回q1中。
如图:
实现代码:
#include <queue>
template <class T>
class Stack
{
public:
Stack(void)
{}
~Stack(void)
{}
void Push_Tail(const T& p);
T DeleteHead();
private:
queue<T> q1;
queue<T> q2;
};
//在栈尾部添加数据
template <class T>
void Stack<T>::Push_Tail(const T& p)
{
//不为空执行push
if (!q1.empty())
{
q1.push(p);
}
else
{
q2.push(p);
}
}
//取出数据
template <class T>
T Stack<T>::DeleteHead()
{
int ret = 0;
//q1为空
if (q1.empty())
{
int i = q2.size();
//将q2的数据pop到只剩下一个
while (i > 1)
{
q1.push(q2.front());
q2.pop();
--i;
}
ret = q2.front();
q2.pop();
}
else//q1不为空
{
int i = q1.size();
while (i > 1)
{
q2.push(q1.front());
q1.pop();
--i;
}
ret = q1.front();
q1.pop();
}
return ret;
}
测试代码:
#include <iostream>
using namespace std;
#include "Queue.h"
#include "Stack.h"
int main()
{
/*Queue<int> q1;
q1.Push_Tail(1);
int ret = q1.DeleteHead();
cout << ret << endl;*/
Stack<int> s1;
s1.Push_Tail(5);
int ret = s1.DeleteHead();
cout << ret << endl;
system("pause");
return 0;
}
优化
q1是专职进出栈的,q2只是个中转站。元素集中存放在一个栈中,但不是指定(q1 或 q2)。
定义两个指针:pushtmp:指向专门进栈的队列q1; tmp:指向临时作为中转站的另一个栈q2
入栈:直接入pushtmp所指队列即可
出栈:把pushtmp的除最后一个元素外全部转移到队列tmp中,然后把刚才剩下q1中的那个元素出队列
(此处就不用指针指针了)效果一样~
优化之后的代码:
#include <queue>
template <class T>
class Stack
{
public:
Stack(void)
{}
~Stack(void)
{}
void Push_Tail(const T& p);
T DeleteHead();
private:
queue<T> q1;
queue<T> q2;
};
//在栈尾部添加数据
template <class T>
void Stack<T>::Push_Tail(const T& p)
{
if (!q1.empty())
{
q1.push(p);
}
else
{
q2.push(p);
}
}
template <class T>
T Stack<T>::DeleteHead()
{
int ret = 0;
if (!q1.empty())
{
while (q1.size() != 1)
{
q2.push(q1.front());
q1.pop();
}
ret = q1.front();
q1.pop();
}
else
{
while (q2.size() != 1)
{
q1.push(q2.front());
q2.pop();
}
ret = q2.front();
q2.pop();
}
return ret;
}