问题1:用两个栈实现一个队列
问题描述及分析:
用两个栈实现一个队列。分别完成在队列尾部插入节点AppendTail和在队列头部删除节点DeleteHead的功能。
栈的特点是先进后出(FILO),而队列的特点是先进先出(FIFO),因此,尾部插入节点相当于入栈操作,很容易实现。但是头部删除节点比较麻烦,我们始终用stack1存储元素,用stack2作为临时空间来导出数据。当stack2为空时,把stack1中的数据逐个弹出,压入stack2中,再从stack2中pop元素;当stack2不为空时,直接从stack2中pop元素即可。当stack1与stack2都为空时,则认为队列为空。
插入删除元素图解:
代码实现:
template<class T>
class Queue
{
public:
Queue()
{}
~Queue()
{}
void AppendTail(const T data)//尾部插入节点
{
s1.push(data);
}
T DeleteHead()//头部删除节点
{
if (s2.empty())
{
if (s1.empty())
{
cout << "队列已空!" << endl;
return 0;
}
while (!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
}
T ret = s2.top();
s2.pop();
return ret;
}
private:
stack<T> s1;
stack<T> s2;
};
问题2:用两个队列实现一个栈
问题分析:
用两个队列实现一个栈,删除时,由于队列是先进先出的,而栈是后进先出,因此假设现在数据在queue1中,我们需要从queue1转移数据到queue2,直到queue1只剩下一个数据为止,再直接从queue1中删除数据,即实现了栈的后进先出。但是每次删除时都需要将数据从一个队列导入到另一个队列,因此插入元素时就不能随便插入,而应该判断哪个队列有数据再向哪个队列中插入数据,否则,元素的入栈顺序就会混乱。但当两个队列都为空时,我们可以随意插入。
插入删除元素图解:
代码实现:
template<class T>
class Stack
{
public:
Stack()
{}
~Stack()
{}
void AppendTail(const T data)
{
if (q1.empty())
{
q2.push(data);
}
else
{
q1.push(data);
}
}
T DeleteHead()
{
T ret=0;
if (q1.empty() && q2.empty())
{
cout << "stack is empty!" << endl;
return ret;
}
if (q1.empty())
{
while (q2.size()>1)
{
q1.push(q2.front());
q2.pop();
}
ret = q2.front();
q2.pop();
}
else
{
while (q1.size()>1)
{
q2.push(q1.front());
q1.pop();
}
ret = q1.front();
q1.pop();
}
return ret;
}
private:
queue<T> q1;
queue<T> q2;
};