使用两个队列实现一个栈
***如果需要栈实现队列点击这里——《 两个栈实现一个队列》
一。栈和队列的区别与联系相同点:
(1)栈和队列都是控制访问点的线性表;
(2)栈和队列都是允许在端点处进行数据的插入和删除的数据结构;
不同点:
(1)栈遵循 先进后出 的原则,即表示只能在一头进行数据的插入和删除,该位置称为“栈顶”,而另外一头称为“栈底”;根据该特性,实现栈时用顺序表比较好;
(2)队列遵循 先进先出 的原则,即只能在队列的尾部插入元素,头部删除元素。根据该特性,在实现队列时用链表比较好
二。根据图片进行分析:
图(1):当栈里面插入元素“abcdef”的时候,元素a在栈底(最后出去),f在栈顶(最先出去);
图(2):将元素“abcde”从q1中头删,然后再q2中尾插进来之后,头删q1中的元素“f”,就相当于实现了栈顶元素的出栈;
图(3):同理,将元素“abcd”从q2中头删,然后尾插到q1中,然后再头删q2中的元素“e”;
图(4):同理,将元素“abc”从q1中头删,然后尾插到q2中,然后再头删q2中的元素“d”;
图(5):同理,将元素“bc删除”;
图(6):当栈又插入一个元素“g”时,此时元素“a”不能从队列中删除,而是将元素“a”插入q1中,再删除q2中的元素“e”,最后再删除元素“a”。
说明:其中红色框代表该队列中的元素出队列,该队列为空。
三。代码如下
1.源代码
#include<iostream>
#include<queue>
#include<assert.h>
using namespace std;
template <class T>
class Stack
{
public:
Stack(){};
~Stack(){};
//实现栈元素的尾部插入
void TailAppend(const T& node)
{
//数据的插入原则:保持一个队列为空,一个队列不为空,往不为空的队列中插入元素
//如果队列1不为空,将数据插入到队列1中
if (!q1.empty())
{
q1.push(node);
}
//如果队列2不为空,将数据插入到队列2中
else
{
q2.push(node);
}
}
//实现栈元素的删除
T& HeadDelete()
{
//定义一个返回值
int ret = 0;
//当队列1不为空,队列2为空,那么将q1的n-1个元素删除并插入到q2中
//,q1剩下最后一个元素,且为我们要的栈顶元素(也叫栈的头删)
if (!q1.empty())
{
//求出q1的长度-1
int num = q1.size();
while (num > 1)
{
//将其他删除插入到q2中
q2.push(q1.front());
q1.pop();
--num;
}
//最后一个给返回值,并且出队列
ret = q1.front();
q1.pop();
}
//当q2不为空时,与队列1的做法,定义是一样的
else
{
int num = q2.size();
while (num > 1)
{
q1.push(q2.front());
q2.pop();
--num;
}
ret = q2.front();
q2.pop();
}
return ret;
}
private:
queue<T> q1;
queue<T> q2;
};
2.测试主代码
int main()
{
Stack<int> s;
s.TailAppend(1);
s.TailAppend(2);
s.TailAppend(3);
cout << "栈顶为: " << s.HeadDelete() << endl;
cout << "栈顶为: " << s.HeadDelete() << endl;
cout << "栈顶为: " << s.HeadDelete() << endl;
return 0;
}
3.测试结果
根据分析加上代码,我相信大家很快就能理解并且掌握了。