用兩個佇列模擬一個棧
阿新 • • 發佈:2019-02-14
有一段時間沒用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互換,這樣方便下次操作。
程式碼如下:
#include <iostream> #include <utility> #include <stack> #include <queue> using namespace std; /* *虛基類,定義了四個方法,pop(),push(),top()和emtpy() *在基類中實現了empty()方法 *除兩個佇列外,還有兩個指向佇列的指標,用以指向用來入棧的佇列和用來出棧的佇列 */ class QueueToStack{ protected: queue<int> q1; queue<int> q2; queue<int> *Push=&q1; queue<int> *Pop=&q2; public: virtual void pop()=0; virtual void push(int n)=0; virtual int top()=0; bool empty(){return q1.empty() && q2.empty();} }; /* *一種用兩個佇列實現棧的方法,入棧時間複雜度為O(1),出棧時間複雜度為O(n) *保證每次入棧元素加入Push佇列隊尾 *Push指標指向的佇列用來入棧,Pop指標指向的佇列作為輔助,每次出棧將Push佇列賦值到Pop上並丟棄Push隊尾元素作為出棧 *出棧完畢後將Push和Pop交換 */ class FastPush: public QueueToStack { public: void pop(); void push(int n); int top(); }; void FastPush::push(int n){ Push->push(n); } int FastPush::top(){ return Push->back(); } void FastPush::pop(){ while(Push->size()>1){ Pop->push(Push->front()); Push->pop(); } Push->pop(); swap(Push,Pop); } /* *另一種實現方法,入棧操作是O(n),出棧操作是O(1) *保證每次入棧之後,Pop佇列的順序就是在棧中的順序 *Push佇列作為輔助,每次入棧完畢後保證為空,入棧時,將元素加入Push佇列,再將Pop佇列複製到Push佇列 *最後將Push和Pop佇列互換 *由於每次入棧完成後Pop佇列中元素的順序都是棧順序的,所以入棧的時候只需要吧Pop佇列賦值到Push後邊 */ class FastPop: public QueueToStack{ public: void pop(); void push(int n); int top(); }; void FastPop::pop(){ Pop->pop(); } int FastPop::top(){ return Pop->front(); } void FastPop::push(int n){ Push->push(n); while(!Pop->empty()){ Push->push(Pop->front()); Pop->pop(); } swap(Push,Pop); } int main() { stack<int> s; QueueToStack *qs1 = new FastPush; QueueToStack *qs2 = new FastPop; for(int i=0;i<10;i++){ s.push(i); qs1->push(i); qs2->push(i); } for(int i=0;i<10;i++){ cout<<s.top()<<"\t"<<qs1->top()<<"\t"<<qs2->top()<<endl; s.pop(); qs1->pop(); qs2->pop(); } return 0; }
執行結果:
G:\>QueueToStack.exe
9 9 9
8 8 8
7 7 7
6 6 6
5 5 5
4 4 4
3 3 3
2 2 2
1 1 1
0 0 0