您的位置:首页 > 其它

使用两个栈实现一个队列+使用两个队列实现一个栈

2017-07-19 01:02 489 查看

使用两个栈实现一个队列

始终维护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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: