用两个队列模拟一个栈

用两个队列模拟一个栈

标签: 数据结构队列栈    http://blog.csdn.net/yin1203014/article/details/47061257
301人阅读 评论(0) 收藏 举报
分类:

目录(?)[+]

    有一段时间没用C++和数据结构的东西了,感觉有点荒废,今天呆着没事把队列实现栈这个问题动手用C++写了一下。

    这里实现了两种方法,一种入栈的复杂度是O(1),出栈O(n),一种入栈O(n),出栈O(1),更好的方法我还没有想到,如果你有更好的方法还望告诉我一下。

    第一种方法

    入栈的时候直接插入一个队(记为A)的队尾,出栈的时候由于要把A队队尾的元素取出,所以就把A中的元素除最后一个外依次放到另一个队列B中,最后一个直接丢弃。完成后把A和B互换,这样下次入栈再插入到A队尾即可。


    第二种方法

    假设B队中元素的顺序就是元素在栈中的顺序,越新加入的越靠近队首。再次入栈一个元素,插入到一个空的队列A中,然后再把B中的元素依次插入A中,这样由于B中的顺序是由旧及新,而A队队首是最新的,所以A队也是由旧及新。完成后把A和B互换,这样方便下次操作。


代码如下:

  1. #include <iostream>  
  2. #include <utility>  
  3. #include <stack>  
  4. #include <queue>  
  5.   
  6. using namespace std;  
  7.   
  8. /* 
  9.  *虚基类,定义了四个方法,pop(),push(),top()和emtpy() 
  10.  *在基类中实现了empty()方法 
  11.  *除两个队列外,还有两个指向队列的指针,用以指向用来入栈的队列和用来出栈的队列 
  12.  */  
  13. class QueueToStack{  
  14.     protected:  
  15.         queue<int> q1;  
  16.         queue<int> q2;  
  17.         queue<int> *Push=&q1;  
  18.         queue<int> *Pop=&q2;  
  19.     public:  
  20.         virtual void pop()=0;  
  21.         virtual void push(int n)=0;  
  22.         virtual int top()=0;  
  23.         bool empty(){return q1.empty() && q2.empty();}  
  24. };  
  25.   
  26. /* 
  27.  *一种用两个队列实现栈的方法,入栈时间复杂度为O(1),出栈时间复杂度为O(n) 
  28.  *保证每次入栈元素加入Push队列队尾 
  29.  *Push指针指向的队列用来入栈,Pop指针指向的队列作为辅助,每次出栈将Push队列赋值到Pop上并丢弃Push队尾元素作为出栈 
  30.  *出栈完毕后将Push和Pop交换 
  31. */  
  32. class FastPush: public QueueToStack {  
  33.     public:  
  34.         void pop();  
  35.         void push(int n);  
  36.         int top();  
  37. };  
  38.   
  39. void FastPush::push(int n){  
  40.     Push->push(n);  
  41. }  
  42.   
  43. int FastPush::top(){  
  44.     return Push->back();  
  45. }  
  46.   
  47. void FastPush::pop(){  
  48.     while(Push->size()>1){  
  49.         Pop->push(Push->front());  
  50.         Push->pop();  
  51.     }  
  52.     Push->pop();  
  53.     swap(Push,Pop);  
  54. }  
  55.   
  56. /* 
  57. *另一种实现方法,入栈操作是O(n),出栈操作是O(1) 
  58. *保证每次入栈之后,Pop队列的顺序就是在栈中的顺序 
  59. *Push队列作为辅助,每次入栈完毕后保证为空,入栈时,将元素加入Push队列,再将Pop队列复制到Push队列 
  60. *最后将Push和Pop队列互换 
  61. *由于每次入栈完成后Pop队列中元素的顺序都是栈顺序的,所以入栈的时候只需要吧Pop队列赋值到Push后边 
  62. */  
  63. class FastPop: public QueueToStack{  
  64.     public:  
  65.         void pop();  
  66.         void push(int n);  
  67.         int top();  
  68. };  
  69.   
  70. void FastPop::pop(){  
  71.     Pop->pop();  
  72. }  
  73.   
  74. int FastPop::top(){  
  75.     return Pop->front();  
  76. }  
  77.   
  78. void FastPop::push(int n){  
  79.     Push->push(n);  
  80.     while(!Pop->empty()){  
  81.         Push->push(Pop->front());  
  82.         Pop->pop();  
  83.     }  
  84.     swap(Push,Pop);  
  85. }  
  86.   
  87.   
  88. int main()  
  89. {  
  90.     stack<int> s;  
  91.     QueueToStack *qs1 = new FastPush;  
  92.     QueueToStack *qs2 = new FastPop;  
  93.     for(int i=0;i<10;i++){  
  94.         s.push(i);  
  95.         qs1->push(i);  
  96.         qs2->push(i);  
  97.     }  
  98.     for(int i=0;i<10;i++){  
  99.         cout<<s.top()<<"\t"<<qs1->top()<<"\t"<<qs2->top()<<endl;  
  100.         s.pop();  
  101.         qs1->pop();  
  102.         qs2->pop();  
  103.     }  
  104.     return 0;  
  105. }  

    运行结果:

  1. G:\>QueueToStack.exe  
  2. 9       9       9  
  3. 8       8       8  
  4. 7       7       7  
  5. 6       6       6  
  6. 5       5       5  
  7. 4       4       4  
  8. 3       3       3  
  9. 2       2       2  
  10. 1       1       1  
  11. 0       0       0


两个队列模拟一个堆栈

标签: include   http://blog.csdn.net/wangyangkobe/article/details/5910362
5255人阅读 评论(1) 收藏 举报
分类:
  1. #include <cstdlib>  
  2. #include <iostream>  
  3. #include <assert.h>  
  4. #include <deque>  
  5. using namespace std;  
  6. /*两个队列模拟一个堆栈*/  
  7. /*队列A、B 
  8. 入栈:将元素依次压入到非空的队列,第一个元素压倒对列A 
  9. 出栈:把队列A的前n-1个元素倒到队列B,把第n个元素去掉。此时数据在B中,下次操作,则对B操作。 
  10. 栈顶:把队列A的前n-1个元素倒到队列B,把第n个元素作为栈顶*/  
  11. template <typename T>  
  12. class MyStack  
  13. {  
  14. public:  
  15.     //入栈,第一个元素进到队列deque1,以后每个元素进到非空的队列  
  16.     void  push(T element)  
  17.     {  
  18.         if (deque1.empty() && deque2.empty())  
  19.         {  
  20.             deque1.push_back(element);  
  21.         }  
  22.         else if (!deque1.empty() && deque2.empty())  
  23.         {  
  24.             deque1.push_back(element);  
  25.         }  
  26.         else if (deque1.empty() && !deque2.empty())  
  27.         {  
  28.             deque2.push_back(element);  
  29.         }  
  30.     }  
  31.     //出栈,将非空队列的前n-1个元素转移到另一个空的队列,删除非空队列的第n个元素  
  32.     void pop()  
  33.     {  
  34.         if (!deque1.empty())  
  35.         {  
  36.             int size = deque1.size();  
  37.             for (int i=0; i<size-1; i++)  
  38.             {  
  39.                 deque2.push_back(deque1.front());  
  40.                 deque1.pop_front();  
  41.             }  
  42.             deque1.pop_front();  
  43.         }  
  44.         else  
  45.         {  
  46.             int size = deque2.size();  
  47.             for (int i=0; i<size-1; i++)  
  48.             {  
  49.                 deque1.push_back(deque2.front());  
  50.                 deque2.pop_front();  
  51.             }  
  52.             deque2.pop_front();  
  53.         }  
  54.     }  
  55.     //栈顶元素,将非空队列的前n-1个元素转移到另一个空的队列,将非空队列的第n个元素返回  
  56.     T top()  
  57.     {  
  58.         if (!deque1.empty())  
  59.         {  
  60.             int size = deque1.size();  
  61.             for (int i=0; i<size-1; i++)  
  62.             {  
  63.                 deque2.push_back(deque1.front());  
  64.                 deque1.pop_front();  
  65.             }  
  66.             T temp = deque1.front();  
  67.             deque1.pop_front();  
  68.             deque2.push_back(temp);  
  69.             return temp;  
  70.         }  
  71.         else  
  72.         {  
  73.             int size = deque2.size();  
  74.             for (int i=0; i<size-1; i++)  
  75.             {  
  76.                 deque1.push_back(deque2.front());  
  77.                 deque2.pop_front();  
  78.             }  
  79.             T temp = deque2.front();  
  80.             deque2.pop_front();  
  81.             deque1.push_back(temp);  
  82.             return temp;  
  83.         }  
  84.     }  
  85.     //栈是否为空  
  86.     bool empty()  
  87.     {  
  88.         return (deque1.empty()&&deque2.empty());  
  89.     }  
  90. private:  
  91.     deque<T> deque1;  
  92.     deque<T> deque2;  
  93. };  
  94. int main(int argc, char *argv[])  
  95. {  
  96.     MyStack<int> my;  
  97.     for (int i=0; i<10; i++)  
  98.     {  
  99.         my.push(i);  
  100.     }  
  101.     while (!my.empty())  
  102.     {  
  103.         cout<<my.top()<<" ";  
  104.         my.pop();  
  105.     }  
  106.     cout<<endl;  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值