两个栈实现一个队列的内容
如果需要两个队列实现栈的点击这里——《两个队列实现一个栈》
1.栈和队列的区别与联系相同点:
(1)栈和队列都是控制访问点的线性表;
(2)栈和队列都是允许在端点处进行数据的插入和删除的数据结构;
不同点:
(1)栈遵循 先进后出 的原则,即表示只能在一头进行数据的插入和删除,该位置称为“栈顶”,而另外一头称为“栈底”;根据该特性,实现栈时用顺序表比较好;
(2)队列遵循 先进先出 的原则,即只能在队列的尾部插入元素,头部删除元素。根据该特性,在实现队列时用链表比较好
2.根据下图可以看出栈实现队列的基本过程
2.我们根据图片进行分析:
图(1):将队列中的元素“1——7”压入stack1中,此时stack2为空;
图(2):将stack1中的元素pop进stack2中,此时pop一下stack2中的元素,就可以达到和队列删除数据一样的顺序了;
图(3):可能有些人很疑惑,就像图3,当stack2只pop了一个元素1时,satck1中可能还会插入元素8,这时如果将stack1中的元素8插入stack2中,在1之后出栈的元素就是8了,显然,这样想是不对的,我们必须规定当stack2中的元素pop完之后,也就是satck2为空时,再插入stack1中的元素。
3.我们实现代码如下
#include<iostream>
#include<stack>
#include<assert.h>
using namespace std;
template<class T>
class Queue
{
public:
//入队列
void push(const T&data){
stack1.push(data);
}
//出队列
T&Pop()
{
T head;
//如果两个栈都是空栈,此时说明队列是空的
if (stack1.empty() && stack2.empty())
cout << "this queue is empty" << endl;
//如果栈2中有元素,那出队列就出栈2中的
if (!stack2.empty())
{
head = stack2.top();
stack2.pop();
}
//此时表明栈2已是空栈,再要出队列的话,那就需要把栈1中的所有元
//素入栈到栈2中,注意一定要是栈1中的所有元素都入栈到栈2中
else
{
while (stack1.size() > 0)
{
stack2.push(stack1.top());
stack1.pop();
}
head = stack2.top();
stack2.pop();
}
return head;
}
T & Front()//获取队头元素,此时队头位于栈2的栈顶
{
//断言两个栈是否为空
assert(!stack1.empty() || !stack2.empty());
//如果栈2为空,且栈1不为空
if (stack2.empty())
{
while (!stack1.empty())
{
//将栈1的顶元素插入栈2中
stack2.push(stack1.top());
//将栈1从队列取出来
stack1.pop();
}
}
return stack2.top();
if (stack2.size() == 0)//当stack2为空时,抛异常
{
throw new exception("queue is empty");
}
}
//判断是否为空
bool empty()
{
if (stack1.empty() && stack2.empty())
{
return true;
}
else
{
return false;
}
}
private:
stack<T> stack1;
stack<T> stack2;
};
4.测试主函数用例如下:
void TestQueue()
{
Queue<int> q;
q.push(1);
q.push(2);
q.push(3);
q.push(4);
q.push(5);
cout << "队列头节点为:> " <<q.Front() << endl;
cout << "队头为:> " << q.Pop() << endl;
cout << "队列头节点为:> " << q.Front() << endl;
}
int main()
{
TestQueue();
system("pause");
return 0;
}
5.测试结果如下