两个栈实现一个队列与两个队列实现一个栈

来源:互联网 发布:ubuntu忘记登录密码 编辑:程序博客网 时间:2024/06/05 00:53

两个栈实现一个队列:

原理方法:用一个栈为主栈,一个栈为辅助栈存放临时元素。

入队:将元素依次压入主栈

出队:先检测辅助栈是否为空,如果非空,那么直接弹出辅助栈顶元素,相当于出队。如果为空,那么将主栈元素倒入到辅助栈中,然后弹出辅助栈顶元素。达到先进先出的目的。

以下是代码:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //两个个栈实现一个队列  
  2. /*#include <iostream>  
  3. #include <time.h>  
  4. #include <windows.h>  
  5. using namespace std;  
  6. #define MAX 10  
  7. struct stack  
  8. {  
  9.     int Array[MAX];  
  10.     int top;  
  11. };  
  12. struct stack s1,s2;  
  13. //初始化一个空栈  
  14. int Init_Stack()  
  15. {  
  16.     s1.top=s2.top = -1;//top为-1表示空栈  
  17.     return 1;  
  18. }  
  19. //入队  
  20. void enqueue(int Array[],int x)  
  21. {  
  22.     if (s1.top==MAX-1)//检测是否栈已满  
  23.     {  
  24.         cout<<"overflow!"<<endl;  
  25.     }   
  26.     else  
  27.     {  
  28.         s1.top++;  
  29.         s1.Array[s1.top]=x;//将元素压入主栈  
  30.     }  
  31. }  
  32. //出队  
  33. int dequeue()  
  34. {  
  35.     if (s1.top==-1&&s2.top==-1)//如果主栈和辅助栈都是空的,那么就出现下溢。提示错误后返回  
  36.     {  
  37.         cout<<"underflow!"<<endl;  
  38.         return -1;  
  39.     }  
  40.    if (s2.top==-1)//如果辅助栈为空,那么就循环地将主栈元素倒入辅助栈  
  41.    {  
  42.       for (int i=s1.top;i>0;i--)  
  43.       {  
  44.           s1.top--;s2.top++;  
  45.           s2.Array[s2.top]=s1.Array[s1.top+1];  
  46.       }  
  47.       s1.top--;  
  48.       return s1.Array[s1.top+1];//返回主栈最后一个元素作为出队元素  
  49.    }   
  50.    else //如果辅助栈不空,那么直接弹出辅助栈栈顶元素作为出队元素  
  51.    {  
  52.        s2.top--;  
  53.        return s2.Array[s2.top+1];  
  54.    }  
  55. }  
  56. void main()  
  57. {  
  58.     int x=0;  
  59.     Init_Stack();  
  60.     srand( (unsigned)time( NULL ) );  
  61.     cout<<"数组中的数据入队中。。。";  
  62.     forint j=0; j <= 100; j++ )      // 打印百分比   
  63.     {  
  64.         cout.width(3);  
  65.         cout << j << "%";  
  66.         Sleep(40);  
  67.         cout << "\b\b\b\b";//\b退格符号  
  68.     }  
  69.         cout << "\n\n";  
  70.     cout<<"Array=";  
  71.     for (int i=0;i<MAX;i++)  
  72.     {  
  73.         x=rand()%100;  
  74.         cout<<x<<" ";  
  75.         enqueue(s1.Array,x);  
  76.     }  
  77.     cout<<endl;  
  78.     cout<<"所有数据入队完毕!"<<endl;  
  79.     cout<<endl;  
  80.     cout<<"数组中的数据出队中。。。";  
  81.     for(  j=0; j <= 100; j++ )      // 打印百分比   
  82.     {  
  83.         cout.width(3);  
  84.         cout << j << "%";  
  85.         Sleep(40);  
  86.         cout << "\b\b\b\b";//\b退格符号  
  87.     }  
  88.     cout << "\n\n";  
  89.     cout<<"Array=";  
  90.     for ( i=0;i<MAX;i++)  
  91.     {  
  92.         cout<<dequeue()<<" ";  
  93.     }  
  94.     cout<<endl;  
  95.     cout<<"所有数据出队完毕!"<<endl;  
  96.     cout<<endl;  
  97.     enqueue(s1.Array, 56);  
  98.     cout<<dequeue()<<endl;  
  99.     cout<<dequeue()<<endl;  
  100.     cout<<dequeue()<<endl;  
  101.     enqueue(s1.Array, 65);  
  102.     enqueue(s1.Array, 10);  
  103.     enqueue(s1.Array, 32);  
  104.     cout<<dequeue()<<endl;  
  105.     cout<<dequeue()<<endl;  
  106.     enqueue(s1.Array, 2);  
  107.     cout<<dequeue()<<endl;        
  108. }  

运行时间为O(n),在进行倒入操作时需要循环倒入,所以时间为n


两个队列实现一个栈:

原理方法:用一个队列为主队列,一个队列为辅助队列存放临时元素。

入栈:将元素依次压入主队列

出栈:先将拥有n个元素的主队列的其中的n-1个元素倒入辅助队列,然后将原主队列的最后剩下的一个元素弹出队列,相当于出栈,这个时候,辅助队列和主队列进行交换,继续进行刚才的出栈操作。

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //两个队列实现一个栈  
  2. #include <iostream>  
  3. #include <time.h>  
  4. #include <windows.h>  
  5. using namespace std;  
  6. #define MAX 10   
  7. struct queue  
  8. {  
  9.     int head;//声明队头指针  
  10.     int tail;//声明队尾指针  
  11.     int length;//声明队列当前含有的元素个数  
  12.     int Array[MAX];//声明数组所能容纳的最大元素个数  
  13. };  
  14. struct queue q1,q2; //声明两个队列结构体全局变量  
  15. void Init_queue(struct queue &q1)//初始化队列  
  16. {  
  17.     q1.head=q1.tail=1;//队列初始时是从数组Array[1]开始的,所以其实Array[0]是数组最后一个元素,而不是Array[MAX-1]!这是需要注意的。  
  18.     q1.length=1;  
  19. }  
  20. //入栈  
  21. int push(int Array[],int x)  
  22. {  
  23.    if (q1.head==q1.tail+1)//进行入队操作的前提判断是否队列已满  
  24.    {  
  25.        cerr<<"overflow!"<<endl;//若已满,那么提示错误后返回。  
  26.        return -1;  
  27.    }  
  28.    else  
  29.    {  
  30.        if (q1.length==0)//恢复队列中没有元素时的初始值q1.length=1;  
  31.        {  
  32.            q1.length++;q2.length++;  
  33.        }  
  34.        q1.length++;q2.length++;//每次入队数组元素个数+1  
  35.        if (q1.tail==q1.length)//队尾指针既然已经指向当前数组最后一个元素的下一个位置  
  36.        {  
  37.            q1.tail=0;//那么元素只能插入Array[0]最后一个元素,原因在Init_queue函数注释中。  
  38.            q1.Array[q1.tail]=x;  
  39.        }   
  40.        else  
  41.        {  
  42.            q1.Array[q1.tail]=x;  
  43.            q1.tail++;  
  44.            if (q1.tail==MAX)//若队尾指针指向数组最后一个元素的下一个位置  
  45.            {  
  46.                q1.length--;q2.length--;//由于两个队列元素个数是从1开始的,那么主和辅助队列元素个数已经超过MAX,所以需要调整为MAX,以便下次入队时插入到Array[0]这个位置  
  47.            }  
  48.        }  
  49.        return q1.tail;  
  50.    }  
  51. }  
  52. //出栈  
  53. int pop()  
  54. {  
  55.     int x=0;  
  56.     if (q1.length<=0)//如果主队列里面有0个元素,那么说明不能进行出队(出栈)操作,直接返回错误提示  
  57.     {  
  58.         cerr<<"underflow"<<endl;  
  59.         return -1;  
  60.     }   
  61.     else  
  62.     {  
  63.         if (q1.tail==0)//通常情况需要返回的是队头指针作为出队元素,那么这里为什么返回队尾指针?因为我们需要用两个队列实现一个栈,那么有n个元素的主栈,把n-1个元素传递给辅助队列后,最后入队的也是将要出栈的元素肯定在主栈队尾。  
  64.         {  
  65.            x=q1.Array[q1.tail];//队尾指针指向0时(其实指向的就是数组最后一位,因为初始化是从1开始的),直接返回Array[0]  
  66.         }  
  67.         else  
  68.         {  
  69.            x=q1.Array[q1.tail-1];//队尾指针指向其它时,由于队尾指针总是指向数组最后一个数据的下一位,那么需要返回的是数组最后一个数据,所以要-1.  
  70.         }  
  71.         while(q1.tail!=q1.head)//队头和队尾相等时,说明已经遍历了整个队列,所以退出循环  
  72.         {  
  73.               
  74.             q2.Array[q2.tail]=q1.Array[q1.head];//将主栈的数据传递给辅助栈  
  75.             if (q2.tail==MAX)//由于需要循环遍历队列,所以当队尾等于数组所能容纳的最大元素个数时,队尾指针自动调整到数组第一个位置。  
  76.             {  
  77.                 q2.tail=0;  
  78.             }  
  79.             else  
  80.             {  
  81.                 q2.tail++;  
  82.             }  
  83.             if (q1.head==MAX)//和上面的if-else类似。  
  84.             {  
  85.                 q1.head=0;  
  86.             }  
  87.             else  
  88.             {  
  89.                 q1.head++;  
  90.             }  
  91.         }  
  92.         if (q1.tail==0)//如果队尾指针等于0,自动指向当前主队列的最后一个元素的下一个位置  
  93.         {  
  94.             q1.tail=q1.length;//这样在下次出队时能够返回队列的最后一个元素。  
  95.         }  
  96.         else  
  97.         {  
  98.             q1.tail--;//如果队尾指针不等于0,那么当前主队列队尾下标指向下一个需要出队的元素。  
  99.         }  
  100.         swap(q1,q2);//原来的主队列转换为辅助队列,原来的辅助队列转换为主队列。  
  101.         q1.tail=q2.tail;//由于转换后,原主队列队尾下标变为辅助队列队尾下标,所以需要将当前辅助队列队尾下标传递给主队列  
  102.         q2.head=q2.tail=1;//辅助队列里的元素个数保持不变,然后其指针恢复为初始状态。由于辅助队列只是起到一个临时保存队列中数据的作用,所以每次主队列有元素出队,就需要初始化辅助队列一下。  
  103.         q1.length--;q2.length--;//每次出队后,需要将辅助和主队列当前拥有的元素个数-1.  
  104.         return x;//主队列队尾元素出队(相当于出栈)  
  105.     }  
  106. }  
  107. void swap(struct queue &q1,struct queue &q2)//辅助队列与主队列之间转换  
  108. {  
  109.   struct queue temp;  
  110.   temp=q1;  
  111.   q1=q2;  
  112.   q2=temp;  
  113. }  
  114. void main()  
  115. {  
  116.     int x=0;  
  117.     Init_queue(q1);  
  118.     Init_queue(q2);  
  119.     srand( (unsigned)time( NULL ) );  
  120.     cout<<"数组中的数据入栈中。。。";  
  121.     forint j=0; j <= 100; j++ )      // 这个循环就是一个看起来很酷的小程序,其实实际作用没有。^_^  
  122.     {  
  123.         cout.width(3);  
  124.         cout << j << "%";  
  125.         Sleep(40);  
  126.         cout << "\b\b\b\b";//\b退格符号  
  127.     }  
  128.     cout << "\n\n";  
  129.     cout<<"Array=";  
  130.     for (int i=0;i<MAX;i++)//对于开始q1和q2两个空栈来说,设置q1为主栈,q2为辅助栈  
  131.     {  
  132.         x=rand()%100;  
  133.         int t=push(q1.Array,x);  
  134.         if (t==-1)//既然队列已满,那么提示不能入栈后,自动跳出循环。  
  135.         {  
  136.             break;  
  137.         }  
  138.         if (q1.tail==0)  
  139.         {  
  140.             cout<<q1.Array[q1.tail]<<" ";  
  141.         }   
  142.         else  
  143.         {  
  144.             cout<<q1.Array[q1.tail-1]<<" ";  
  145.         }  
  146.     }  
  147.     cout<<endl;  
  148.     cout<<"所有数据入栈完毕!"<<endl;  
  149.     cout<<endl;  
  150.     cout<<"数组中的数据出栈中。。。";  
  151.     for(  j=0; j <= 100; j++ )      // 打印百分比   
  152.     {  
  153.         cout.width(3);  
  154.         cout << j << "%";  
  155.         Sleep(40);  
  156.         cout << "\b\b\b\b";//\b退格符号  
  157.     }  
  158.     cout << "\n\n";  
  159.     cout<<"Array=";  
  160.     for ( i=0;i<MAX;i++)  
  161.     {  
  162.         cout<<pop()<<" ";  
  163.     }  
  164.     cout<<endl;  
  165.     cout<<"所有数据出栈完毕!"<<endl;  
  166.     cout<<endl;  
  167. }  
运行时间:由于需要将主队列循环倒入到辅助队列中,所以总时间为O(n).
0 0
原创粉丝点击