大家都知道,栈是先进后出,队列是先进先出的。那么如何使用栈来完成队列的功能,又如何用队列完成栈的功能呢?
一、两个栈实现队列
两个栈实现队列的方法就是将一个栈用来当作进入元素的入口,当要取出元素的时候,就将这个栈中的元素转入到另外一个栈中,由于先进后出,此时第二个栈中的元素顺序就和第一个栈中的元素顺序相反,这样就实现了一个队列的功能。具体流程如下:
1、将元素进栈
2、当需要先删除队头元素时,先检查stack2是否为空,如果为空,就将stack1中的元素转移至stack2中,否则直接删除stack2中的元素
然后删除元素4
当需要添加新元素5时,就将5添加到stack1中
这样就简单的利用栈实现了队列的功能。下面用代码的方式阐述这一过程:
#include <stack>
#include <exception>
template <typename T> class CQueue { public: CQueue(void){}; ~CQueue(void){}; // 在队列末尾添加一个结点 void appendTail(const T& node){ stack1.push(node); } // 删除队列的头结点 T deleteHead(){ if(stack2.size()<= 0){ //检查stack2是否为空 while(stack1.size()>0) //如果stack2为空,且stack1中有元素,就将stack1中的元素移至stack2中 { T& data = stack1.top(); stack1.pop(); stack2.push(data); } } if(stack2.size() == 0) //如果此时stack2还是为空,那么就说明此时两个栈中都没有元素,那么这个队列就为空 throw new exception("queue is empty"); T head = stack2.top(); //将stack2中的元素自上而下的弹出 stack2.pop(); return head; } private: stack<T> stack1; stack<T> stack2; };
二、两个队列实现栈
利用队列实现栈其实还是利用另一个来当做缓冲容器,具体流程图如下:
1、依次进入1、2、3、4
2、如果需要弹出元素4,我们需要先将queue1中的1、2、3元素依次进入queue2中,然后将元素4出队,这样就实现了后进先出
3、如果需要添加元素,就先判断哪个队列不为空,然后在不为空的队列中添加新元素,如在此,就在queue2队列中添加新元素5
这样就简单的实现了用队列来模拟栈的过程,具体的源代码如下:
#include <queue> #include <assert.h> using namespace std; template<typename T> class CStack{ private: queue<T> queue1; queue<T> queue2; T TransformData(queue<T> q1, queue<T> q2){ //这个函数用来移动队列中的元素,直到队列中只剩下一个元素的时候,而这个元素就是我们需要删除的元素 while (q1.size() > 1){ T& data = q1.front(); q1.pop(); q2.push(data); } T head = q1.front(); q1.pop(); return head; } public: CStack(){} ~CStack(){} T Pop(){ assert(!queue1.empty() || !queue2.empty()); //要判断两个队列都不是空 T data; if (!queue1.empty()){ data=TransformData(queue1, queue2); } else{ data=TransformData(queue2, queue1); } return data; } void Push(const T& t){ if (queue1.empty()){ queue2.push(t); } else{ queue2.push(t); } } };