1. 程式人生 > >用兩個佇列模擬一個棧

用兩個佇列模擬一個棧

    有一段時間沒用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