在做这道题之前,我们首先要搞清楚队列和栈的特点。
队列:先进先出,即插入数据在队尾进行,删除数据在队头进行;
栈:后进先出,即插入与删除数据均在栈顶进行。
POP:
如果我们要实现一个栈,我们先进入的数据一定是先出去的,怎么样利用队列实现这个特点呢?我们可以利用两个队列来进行数据顺序的调整。当我们需要删除数据时,我们可以先将数据push到一个队列当中,pop时,因为队列是先进先出的,所以我们可以将队尾的元素保留下来,其余元素按照出队的顺序入队到另外一个队列当中,然后pop第一个队列的最后一个元素,这样就实现了栈的删除操作。
上图是栈进行一次删除数据的示意图,当我们需要再次删除数据时,我们需要将queue2的队尾数据保存下来进行pop,其余数据入队到另外一个队列当中。就这样利用两个队列来对数据进行来回交换实现栈。
写代码的时候需要注意当两个队列都为空的时候是没有办法pop数据的。
PUSH:
当我们要插入数据的时候,我们需要对队列进行判断,将数据插入到非空的队列当中。这样的话pop时我们分情况讨论的时候只用分队列为空和不为空两种情况,有利于代码的编写。若是插入数据时将数据插入到非空队列,那就可能出现第三种情况,两个队列都不为空,这个时候写的代码就比较复杂了。所以选择第一种方式。
#include<iostream>
#include<queue>using namespace std;
template<typename T>
class Satck
{
public:Satck(){}~Satck(){}void Push(const T& data){if (queue1.size()>0)//q1非空{queue1.push( data);}else if (queue2.size() > 0)//q2非空{queue2.push( data);}else//q1,q2都为空{queue1.push( data);}}void Pop(){if (queue1.size() != NULL ){while (queue1.size()!=1){queue2.push(queue1.front());queue1.pop();}queue1.pop();}else{while (queue2.size() != 1){queue1.push(queue2.front());queue2.pop();}queue2.pop();}}T& Top(){if (queue1.size() > 0){return queue1.front();}else{return queue2.front();}}bool Empty(){if (queue1.empty() && queue2.empty()){return true ;}elsereturn false ;}size_t Size(){if (queue1.empty() && queue2.empty()){return 0;}else if (queue1.size() > 0){return queue1.size();}else{return queue2.size();}}
private:queue<T > queue1;queue<T > queue2;
};void funtest()
{Satck<int > stack;stack.Push(1);stack.Push(2);stack.Push(3);stack.Push(4);stack.Push(5);cout << stack.Size() << endl;cout << stack.Empty() << endl;cout << stack.Top() << endl;stack.Pop();cout << stack.Top() << endl;stack.Push(5);stack.Pop();}
int main()
{funtest();return 0;
}