题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数,appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。


思路:首先要明确的是,看到这道题目,我们最先应该想到的是用C++来实现之。为什么?因为看到栈和队列,如果用C来实现的话,我们还要先去实现push和pop等函数,而C++中的已经为我们实现了这一系列函数,我们直接调用它们即可。

再来考虑实现,栈是后进先出(或先进后出,whatever)的结构,而队列是先进先出的结构。举个例子,我们往输入1 2 3 4 5 6,栈输出顺序则是6 5 4 3 2 1,而队列的输出顺序则是1 2 3 4 5 6,即栈是反向输出,而队列则是原样输出。既然一个栈是反向,那两个栈呢?不就原样了吗?是啊,“反向的反向”就等于“原样”啊。读者可以以此类推,用三个栈就又反向了。

说了这么多,那我们怎么实现呢?我们把两个栈(称为s1和s2)看成是一个整体,用外部来看它就是一个队列。当我们向该整体输入数据时,该数据就存到s1里,再来一个数据又存到s1里去,来多少数据我都存到s1里去。当我们要从该整体读数据时,我们就从s2里面读。读者可能会问了,你把数据都存到s1里面去了,s2里面没有数据,你怎么读?这是个好问题,s2里面没数据,但s1里面有啊,可以从s1里面免费拿啊,谁叫我们是一个整体呢。当s2里面没数据时,就把s1里面的数据全都pop出来,push到s2里面去。


源代码:

#include <iostream>
#include <stack>
using namespace std;

class Queue
{
public:
	Queue(){};
	void appendTail(int data);
	int deleteHead();
	bool isEmpty();
private:
	stack<int> s1;
	stack<int> s2;
};

void Queue::appendTail(int data)
{
	s1.push(data);
}

int Queue::deleteHead()
{
	if(s2.empty())
	{
		while(!s1.empty())
		{
			int d = s1.top();
			s1.pop();
			s2.push(d);
		}
	}
	
	int d = s2.top();
	s2.pop();
	return d;
}

bool Queue::isEmpty()
{
	if(s1.empty() && s2.empty())
		return true;
		
	return false;
}

int main()
{
	Queue q;
	for(int i=0;i<10;i++)
		q.appendTail(i);
	
	while(!q.isEmpty())
		cout << q.deleteHead() << " ";
}