http://blog.csdn.net/z84616995z/article/details/19204529
兩個棧實現一個隊列:
原理方法:用一個棧為主棧,一個棧為輔助棧存放臨時元素。
入隊:將元素依次壓入主棧
出隊:先檢測輔助棧是否為空,如果非空,那么直接彈出輔助棧頂元素,相當于出隊。如果為空,那么將主棧元素倒入到輔助棧中,然后彈出輔助棧頂元素。達到先進先出的目的。
以下是代碼:
[cpp]?view plain?copy
- //兩個個棧實現一個隊列??
- /*#include?<iostream>??
- #include?<time.h>??
- #include?<windows.h>??
- using?namespace?std;??
- #define?MAX?10??
- struct?stack??
- {??
- ????int?Array[MAX];??
- ????int?top;??
- };??
- struct?stack?s1,s2;??
- //初始化一個空棧??
- int?Init_Stack()??
- {??
- ????s1.top=s2.top?=?-1;//top為-1表示空棧??
- ????return?1;??
- }??
- //入隊??
- void?enqueue(int?Array[],int?x)??
- {??
- ????if?(s1.top==MAX-1)//檢測是否棧已滿??
- ????{??
- ????????cout<<"overflow!"<<endl;??
- ????}???
- ????else??
- ????{??
- ????????s1.top++;??
- ????????s1.Array[s1.top]=x;//將元素壓入主棧??
- ????}??
- }??
- //出隊??
- int?dequeue()??
- {??
- ????if?(s1.top==-1&&s2.top==-1)//如果主棧和輔助棧都是空的,那么就出現下溢。提示錯誤后返回??
- ????{??
- ????????cout<<"underflow!"<<endl;??
- ????????return?-1;??
- ????}??
- ???if?(s2.top==-1)//如果輔助棧為空,那么就循環地將主棧元素倒入輔助棧??
- ???{??
- ??????for?(int?i=s1.top;i>0;i--)??
- ??????{??
- ??????????s1.top--;s2.top++;??
- ??????????s2.Array[s2.top]=s1.Array[s1.top+1];??
- ??????}??
- ??????s1.top--;??
- ??????return?s1.Array[s1.top+1];//返回主棧最后一個元素作為出隊元素??
- ???}???
- ???else?//如果輔助棧不空,那么直接彈出輔助棧棧頂元素作為出隊元素??
- ???{??
- ???????s2.top--;??
- ???????return?s2.Array[s2.top+1];??
- ???}??
- }??
- void?main()??
- {??
- ????int?x=0;??
- ????Init_Stack();??
- ????srand(?(unsigned)time(?NULL?)?);??
- ????cout<<"數組中的數據入隊中。。。";??
- ????for(?int?j=0;?j?<=?100;?j++?)??????//?打印百分比???
- ????{??
- ????????cout.width(3);??
- ????????cout?<<?j?<<?"%";??
- ????????Sleep(40);??
- ????????cout?<<?"\b\b\b\b";//\b退格符號??
- ????}??
- ????????cout?<<?"\n\n";??
- ????cout<<"Array=";??
- ????for?(int?i=0;i<MAX;i++)??
- ????{??
- ????????x=rand()%100;??
- ????????cout<<x<<"?";??
- ????????enqueue(s1.Array,x);??
- ????}??
- ????cout<<endl;??
- ????cout<<"所有數據入隊完畢!"<<endl;??
- ????cout<<endl;??
- ????cout<<"數組中的數據出隊中。。。";??
- ????for(??j=0;?j?<=?100;?j++?)??????//?打印百分比???
- ????{??
- ????????cout.width(3);??
- ????????cout?<<?j?<<?"%";??
- ????????Sleep(40);??
- ????????cout?<<?"\b\b\b\b";//\b退格符號??
- ????}??
- ????cout?<<?"\n\n";??
- ????cout<<"Array=";??
- ????for?(?i=0;i<MAX;i++)??
- ????{??
- ????????cout<<dequeue()<<"?";??
- ????}??
- ????cout<<endl;??
- ????cout<<"所有數據出隊完畢!"<<endl;??
- ????cout<<endl;??
- ????enqueue(s1.Array,?56);??
- ????cout<<dequeue()<<endl;??
- ????cout<<dequeue()<<endl;??
- ????cout<<dequeue()<<endl;??
- ????enqueue(s1.Array,?65);??
- ????enqueue(s1.Array,?10);??
- ????enqueue(s1.Array,?32);??
- ????cout<<dequeue()<<endl;??
- ????cout<<dequeue()<<endl;??
- ????enqueue(s1.Array,?2);??
- ????cout<<dequeue()<<endl;????????
- }??
運行時間為O(n),在進行倒入操作時需要循環倒入,所以時間為n
兩個隊列實現一個棧:
原理方法:用一個隊列為主隊列,一個隊列為輔助隊列存放臨時元素。
入棧:將元素依次壓入主隊列
出棧:先將擁有n個元素的主隊列的其中的n-1個元素倒入輔助隊列,然后將原主隊列的最后剩下的一個元素彈出隊列,相當于出棧,這個時候,輔助隊列和主隊列進行交換,繼續進行剛才的出棧操作。
[cpp]?view plain?copy
- //兩個隊列實現一個棧??
- #include?<iostream>??
- #include?<time.h>??
- #include?<windows.h>??
- using?namespace?std;??
- #define?MAX?10???
- struct?queue??
- {??
- ????int?head;//聲明隊頭指針??
- ????int?tail;//聲明隊尾指針??
- ????int?length;//聲明隊列當前含有的元素個數??
- ????int?Array[MAX];//聲明數組所能容納的最大元素個數??
- };??
- struct?queue?q1,q2;?//聲明兩個隊列結構體全局變量??
- void?Init_queue(struct?queue?&q1)//初始化隊列??
- {??
- ????q1.head=q1.tail=1;//隊列初始時是從數組Array[1]開始的,所以其實Array[0]是數組最后一個元素,而不是Array[MAX-1]!這是需要注意的。??
- ????q1.length=1;??
- }??
- //入棧??
- int?push(int?Array[],int?x)??
- {??
- ???if?(q1.head==q1.tail+1)//進行入隊操作的前提判斷是否隊列已滿??
- ???{??
- ???????cerr<<"overflow!"<<endl;//若已滿,那么提示錯誤后返回。??
- ???????return?-1;??
- ???}??
- ???else??
- ???{??
- ???????if?(q1.length==0)//恢復隊列中沒有元素時的初始值q1.length=1;??
- ???????{??
- ???????????q1.length++;q2.length++;??
- ???????}??
- ???????q1.length++;q2.length++;//每次入隊數組元素個數+1??
- ???????if?(q1.tail==q1.length)//隊尾指針既然已經指向當前數組最后一個元素的下一個位置??
- ???????{??
- ???????????q1.tail=0;//那么元素只能插入Array[0]最后一個元素,原因在Init_queue函數注釋中。??
- ???????????q1.Array[q1.tail]=x;??
- ???????}???
- ???????else??
- ???????{??
- ???????????q1.Array[q1.tail]=x;??
- ???????????q1.tail++;??
- ???????????if?(q1.tail==MAX)//若隊尾指針指向數組最后一個元素的下一個位置??
- ???????????{??
- ???????????????q1.length--;q2.length--;//由于兩個隊列元素個數是從1開始的,那么主和輔助隊列元素個數已經超過MAX,所以需要調整為MAX,以便下次入隊時插入到Array[0]這個位置??
- ???????????}??
- ???????}??
- ???????return?q1.tail;??
- ???}??
- }??
- //出棧??
- int?pop()??
- {??
- ????int?x=0;??
- ????if?(q1.length<=0)//如果主隊列里面有0個元素,那么說明不能進行出隊(出棧)操作,直接返回錯誤提示??
- ????{??
- ????????cerr<<"underflow"<<endl;??
- ????????return?-1;??
- ????}???
- ????else??
- ????{??
- ????????if?(q1.tail==0)//通常情況需要返回的是隊頭指針作為出隊元素,那么這里為什么返回隊尾指針?因為我們需要用兩個隊列實現一個棧,那么有n個元素的主棧,把n-1個元素傳遞給輔助隊列后,最后入隊的也是將要出棧的元素肯定在主棧隊尾。??
- ????????{??
- ???????????x=q1.Array[q1.tail];//隊尾指針指向0時(其實指向的就是數組最后一位,因為初始化是從1開始的),直接返回Array[0]??
- ????????}??
- ????????else??
- ????????{??
- ???????????x=q1.Array[q1.tail-1];//隊尾指針指向其它時,由于隊尾指針總是指向數組最后一個數據的下一位,那么需要返回的是數組最后一個數據,所以要-1.??
- ????????}??
- ????????while(q1.tail!=q1.head)//隊頭和隊尾相等時,說明已經遍歷了整個隊列,所以退出循環??
- ????????{??
- ??????????????
- ????????????q2.Array[q2.tail]=q1.Array[q1.head];//將主棧的數據傳遞給輔助棧??
- ????????????if?(q2.tail==MAX)//由于需要循環遍歷隊列,所以當隊尾等于數組所能容納的最大元素個數時,隊尾指針自動調整到數組第一個位置。??
- ????????????{??
- ????????????????q2.tail=0;??
- ????????????}??
- ????????????else??
- ????????????{??
- ????????????????q2.tail++;??
- ????????????}??
- ????????????if?(q1.head==MAX)//和上面的if-else類似。??
- ????????????{??
- ????????????????q1.head=0;??
- ????????????}??
- ????????????else??
- ????????????{??
- ????????????????q1.head++;??
- ????????????}??
- ????????}??
- ????????if?(q1.tail==0)//如果隊尾指針等于0,自動指向當前主隊列的最后一個元素的下一個位置??
- ????????{??
- ????????????q1.tail=q1.length;//這樣在下次出隊時能夠返回隊列的最后一個元素。??
- ????????}??
- ????????else??
- ????????{??
- ????????????q1.tail--;//如果隊尾指針不等于0,那么當前主隊列隊尾下標指向下一個需要出隊的元素。??
- ????????}??
- ????????swap(q1,q2);//原來的主隊列轉換為輔助隊列,原來的輔助隊列轉換為主隊列。??
- ????????q1.tail=q2.tail;//由于轉換后,原主隊列隊尾下標變為輔助隊列隊尾下標,所以需要將當前輔助隊列隊尾下標傳遞給主隊列??
- ????????q2.head=q2.tail=1;//輔助隊列里的元素個數保持不變,然后其指針恢復為初始狀態。由于輔助隊列只是起到一個臨時保存隊列中數據的作用,所以每次主隊列有元素出隊,就需要初始化輔助隊列一下。??
- ????????q1.length--;q2.length--;//每次出隊后,需要將輔助和主隊列當前擁有的元素個數-1.??
- ????????return?x;//主隊列隊尾元素出隊(相當于出棧)??
- ????}??
- }??
- void?swap(struct?queue?&q1,struct?queue?&q2)//輔助隊列與主隊列之間轉換??
- {??
- ??struct?queue?temp;??
- ??temp=q1;??
- ??q1=q2;??
- ??q2=temp;??
- }??
- void?main()??
- {??
- ????int?x=0;??
- ????Init_queue(q1);??
- ????Init_queue(q2);??
- ????srand(?(unsigned)time(?NULL?)?);??
- ????cout<<"數組中的數據入棧中。。。";??
- ????for(?int?j=0;?j?<=?100;?j++?)??????//?這個循環就是一個看起來很酷的小程序,其實實際作用沒有。^_^??
- ????{??
- ????????cout.width(3);??
- ????????cout?<<?j?<<?"%";??
- ????????Sleep(40);??
- ????????cout?<<?"\b\b\b\b";//\b退格符號??
- ????}??
- ????cout?<<?"\n\n";??
- ????cout<<"Array=";??
- ????for?(int?i=0;i<MAX;i++)//對于開始q1和q2兩個空棧來說,設置q1為主棧,q2為輔助棧??
- ????{??
- ????????x=rand()%100;??
- ????????int?t=push(q1.Array,x);??
- ????????if?(t==-1)//既然隊列已滿,那么提示不能入棧后,自動跳出循環。??
- ????????{??
- ????????????break;??
- ????????}??
- ????????if?(q1.tail==0)??
- ????????{??
- ????????????cout<<q1.Array[q1.tail]<<"?";??
- ????????}???
- ????????else??
- ????????{??
- ????????????cout<<q1.Array[q1.tail-1]<<"?";??
- ????????}??
- ????}??
- ????cout<<endl;??
- ????cout<<"所有數據入棧完畢!"<<endl;??
- ????cout<<endl;??
- ????cout<<"數組中的數據出棧中。。。";??
- ????for(??j=0;?j?<=?100;?j++?)??????//?打印百分比???
- ????{??
- ????????cout.width(3);??
- ????????cout?<<?j?<<?"%";??
- ????????Sleep(40);??
- ????????cout?<<?"\b\b\b\b";//\b退格符號??
- ????}??
- ????cout?<<?"\n\n";??
- ????cout<<"Array=";??
- ????for?(?i=0;i<MAX;i++)??
- ????{??
- ????????cout<<pop()<<"?";??
- ????}??
- ????cout<<endl;??
- ????cout<<"所有數據出棧完畢!"<<endl;??
- ????cout<<endl;??
- }??