用两个栈实现一个队列

来源:互联网 发布:网络兼职能信吗 编辑:程序博客网 时间:2024/06/05 01:18
                         用两个栈实现一个队列1、线性表分为:顺序表和链表。栈:只允许在尾上(即是栈顶)进行插入与删除。队列:它是在队尾插入,队头删除。2、栈选数组(即顺序表)结构时(比选链表结构更好):因为选数组结构可以进行size++与size--,而且效率高。     栈选链表结构:3、队列选数组结构时:选数组结构不好,因为删除时需要整体前移,因为队列是在队头进行删除,删除了队头元素时,其后面所跟的其他元素就需要整体向前移一位。效率较低。     队列选链表结构时:比选数组结构好,因为插入和删除元素时方便。#include <iostream>#include <stack>#include <assert.h>using namespace std;//2、两个栈实现一个队列//思路:当两个栈都为空时,只能做入队操作,当两个栈不都为空时,入队、出队操作都可以实现。//      inSta主要用于入栈,outSta主要用于出栈//过程://      入队:1、当outSta为空时,入队操作相当于对inSta做入栈操作(包括inSta为空和inSta不为空两种情况)//            2、当inSta为空,outSta不为空(即上一操作为出栈,inSta转移到outSta的元素没有转移回inSta)时,此时先把outSta的所有元素出栈,//               并按照出栈顺序入栈到inSta,然后再把此时要入队列的元素入栈到inSta//            PS:不会出现inSta不为空,outSta不为空的情况,这种情况只会在前一操作为入队列的出队列过程中(inSta的元素除栈底元素外全部转移//                到outSta),然后这一操作执行前outSta为空,执行后,inSta为空//      出队:1、当inSta、outSta都为空时,队列里面无元素,无法实现出栈//            2、当inSta不为空,outSta为空时,把inSta除栈底元素外的所有元素出栈,并按照出栈顺序入栈到outSta,把inSta的栈底元素出栈//            3、当inSta为空,outSta不为空时,说明上一操作为出栈,inSta转移到outSta的元素没有转移回inSta,此时把outSta的栈顶元素出栈即可//            PS:不会出现两个栈都不为空的情况,这种情况只会在前一操作为入队列的出队列时,然后这一操作执行前outSta为空,执行后,//                Stack1为空template<typename T>class TwoStackForQueue{public:TwoStackForQueue(){//利用stack的构造函数完成}TwoStackForQueue(const TwoStackForQueue<T>& que){//调用stack的赋值运算符重载/拷贝构造函数inSta = que.inSta;outSta = que.outSta;}~TwoStackForQueue(){//这儿不用做什么事情,两个栈开辟的空间由satck释放}void Push(const T& t){if (outSta.size() == 0)       //说明上一操作为入队操作或队列此时为空{inSta.push(t);}else{//先把outSta里面的元素按其出栈顺序入栈到inStawhile (outSta.size() != 0){inSta.push(outSta.top());outSta.pop();}inSta.push(t);}}void Pop(){assert(inSta.size() != 0 || outSta.size() != 0);    //队列为空的情况if (outSta.size() == 0){//把inSta的栈底元素留下,直接出栈它的栈底元素即可while (inSta.size() != 1){outSta.push(inSta.top());inSta.pop();}inSta.pop();}//说明上一操作为出栈,此时直接出栈outSta的栈顶元素即可else{outSta.pop();}}T& Front(){assert(inSta.size() != 0 || outSta.size() != 0);    //队列为空的情况if (outSta.size() != 0){return outSta.top();}else{//这儿不要图方便,留下inSta的栈底元素不移动,直接返回inSta的栈底元素,因为这样做的话使inSta和outSat都不为空了,//而上面的Push与Pop没有对这种情况进行处理while (inSta.size() != 0){outSta.push(inSta.top());inSta.pop();}return outSta.top();}}T& Back(){assert(inSta.size() != 0 || outSta.size() != 0);    //队列为空的情况if (outSta.size() != 0){//这儿不要图方便,留下outSta的栈底元素不移动,直接返回outSta的栈底元素,因为这样做的话使inSta和outSat都不为空了,//而上面的Push与Pop没有对这种情况进行处理while (outSta.size() != 0){inSta.push(outSta.top());outSta.pop();}return inSta.top();}else{return outSta.top();}}bool Empty(){if (inSta.size() == 0 && outSta.size() == 0){return true;}else{return false;}}size_t Size(){//要么两个栈都为空-->返回0,要么一个为空一个不为空-->返回两个栈中不为空的栈的size即可return inSta.size() > outSta.size() ? inSta.size() : outSta.size();}//为了测试正确性,写一个输出运算符重载template<typename T>friend ostream& operator<<(ostream& os, const TwoStackForQueue<T>& que);private:stack<T> inSta;stack<T> outSta;};template<typename T>ostream& operator<<(ostream& os, const TwoStackForQueue<T>& que){TwoStackForQueue<T> coutque(que);os << "Queue: ";//根据入队序列输出 inSta栈顶-->最后入队的元素    outSta-->最先入队的元素//所以先把元素都先入栈到outSta,每次输出outSta的栈顶元素,并把它出栈,直到outSta里面没有元素即可if (coutque.inSta.size() > 0){while (coutque.inSta.size() > 0){coutque.outSta.push(coutque.inSta.top());coutque.inSta.pop();}}while (coutque.outSta.size() > 0){os << coutque.outSta.top() << "  ";coutque.outSta.pop();}os << "NULL";return os;}void Test(){TwoStackForQueue<int> que;que.Push(0);que.Push(5);que.Push(4);que.Push(1);que.Push(2);que.Push(3);cout << que << endl;que.Pop();que.Pop();cout << que << endl;cout << que.Front() << endl;cout << que.Back() << endl;cout << que.Empty() << endl;cout << que.Size() << endl;}int main(){Test();return 0;}//优化版一//2、两个栈实现一个队列//思路:当两个栈都为空时,只能做入队操作,当两个栈不都为空时,入队、出队操作都可以实现。//      inSta只用于入栈,outSta只用于出栈//过程://      入队:不管outSta是否为空,都直接把元素入栈到inSta//      出队:1、当inSta、outSta都为空时,队列里面无元素,无法实现出栈//            2、当outSta为空时,把inSta除栈底元素外的所有元素出栈,并按照出栈顺序入栈到outSta,把inSta的栈底元素出栈//            3、当outSta不为空时,说明上一操作为出栈,此时把outSta的栈顶元素出栈即可template<typename T>class TwoStackForQueue{public:TwoStackForQueue(){//利用stack的构造函数构造inSta与outSta即可}TwoStackForQueue(const TwoStackForQueue& que){inSta = que.inSta;outSta = que.outSta;}~TwoStackForQueue(){//inSta和outSta空间的释放由stack类来完成}void Push(const T& t){inSta.push(t);}void Pop(){assert(inSta.size() != 0 || outSta.size() != 0);    //队列为空的情况if (outSta.size() == 0){//说明此时是第一次执行出对列或之前outSta里面的数据全部被出栈了while (inSta.size() != 1){outSta.push(inSta.top());inSta.pop();}inSta.pop();}//说明之前留在outSta里面的元素没有被全部出栈else{outSta.pop();}}T& Front(){assert(inSta.size() != 0 || outSta.size() != 0);    //队列为空的情况if (outSta.size() != 0){return outSta.top();}else{//当outSta为空时,说明队首元素即是inSta的栈底元素,返回它即可while (inSta.size() != 1){outSta.push(inSta.top());inSta.pop();}return inSta.top();}}T& Back(){assert(inSta.size() != 0 || outSta.size() != 0);    //队列为空的情况if (inSta.size() != 0){return inSta.top();}else{//当inSta为空时,说明队尾元素即是outSta的栈底元素,返回它即可while (outSta.size() != 1){inSta.push(outSta.top());outSta.pop();}return outSta.top();}}bool Empty(){if (inSta.size() == 0 && outSta.size() == 0){return true;}else{return false;}}size_t Size(){//返回两个栈的元素个数和return inSta.size() + outSta.size();}//为了测试正确性,写一个输出运算符重载template<typename T>friend ostream& operator<<(ostream& os, const TwoStackForQueue<T>& que);private:stack<T> inSta;stack<T> outSta;};template<typename T>ostream& operator<<(ostream& os, const TwoStackForQueue<T>& que){TwoStackForQueue<T> coutque(que);os << "Queue: ";//根据入队序列输出 inSta不为空:inSta栈顶-->最后入队的元素   outSta不为空:outSta栈顶-->最先入队的元素while (coutque.outSta.size() > 0){os << coutque.outSta.top() << "  ";coutque.outSta.pop();}while (coutque.inSta.size() > 0){coutque.outSta.push(coutque.inSta.top());coutque.inSta.pop();}while (coutque.outSta.size() > 0){os << coutque.outSta.top() << "  ";coutque.outSta.pop();}os << "NULL";return os;}void Test(){TwoStackForQueue<int> que;que.Push(0);que.Push(5);que.Push(4);que.Push(1);que.Push(2);que.Push(3);cout << que << endl;que.Pop();que.Pop();cout << que << endl;cout << que.Front() << endl;cout << que.Back() << endl;cout << que.Empty() << endl;cout << que.Size() << endl;}int main(){Test();return 0;}

本文出自 “10911544” 博客,请务必保留此出处http://10921544.blog.51cto.com/10911544/1773535

0 0