1. 程式人生 > >用兩個佇列實現一個棧

用兩個佇列實現一個棧

題目:
說明如何用兩個佇列來實現一個棧,並分析有關棧操作的執行時間。

解法:
1.有兩個佇列q1和q2,先往q1內插入a,b,c,這做的都是棧的push操作。
2.現在要做pop操作,即要得到c,這時可以將q1中的a,b兩個元素全部dequeue並存入q2中,這時q2中元素為a,b,對q1再做一次dequeue操作即可得到c。
3.如果繼續做push操作,比如插入d,f,則把d,f插入到q2中,
4.此時若要做pop操作,則做步驟2
5.以此類推,就實現了用兩個佇列來實現一個棧的目的。

注意在此過程中,新push進來的元素總是插入到非空佇列中,空佇列則用來儲存pop操作之後的那些元素,那麼此時空佇列不為空了,原來的非空佇列變為空了,總是這樣迴圈。

對於push和pop操作,其時間為O(n).

#include <iostream>
#include <stack>
#include <assert.h>
using namespace std;

// 兩個佇列實現一個棧

template<typename T> class CStack
{
public:
	CStack() {}
	~CStack() {}
	void mypush(const T& element);
	void mypop();
	
private:
	deque <T> m_queue1;
	deque <T> m_queue2;
};
template<typename T> void CStack<T>::mypop()
{//程式碼與原文程式碼略有不同
if (m_queue1.size() == 0) { if (m_queue2.size() == 0) { cout<<"Stack is empty!!!"<<endl; return; } while (m_queue2.size() > 1) { T data = m_queue2.front(); m_queue2.pop_front(); m_queue1.push_back(data); } assert(m_queue2.size() == 1); //確保佇列2內有一個元素 T result = m_queue2.front();//【注】原文此處有誤:T& result;如果此外用引用,那麼下一句程式碼卻pop掉了原來的數,所以會輸出錯誤值
m_queue2.pop_front(); cout << result << endl; } else { while (m_queue1.size() > 1) { T data = m_queue1.front(); m_queue1.pop_front(); m_queue2.push_back(data); } assert(m_queue1.size() == 1); //確保佇列1內有一個元素 T result = m_queue1.front();//【注】同上! m_queue1.pop_front(); cout << result << endl; } } template<typename T> void CStack<T>::mypush(const T& element) { /* if (m_queue1.size() > 0)//註釋掉的這部分為轉載文章中的程式碼,我覺得完全只用下面的一句話就可以 { m_queue1.push_back(element); } else if (m_queue2.size() > 0) { m_queue2.push_back(element); } else { m_queue1.push_back(element); }*/ m_queue1.push_back(element); } int main() { CStack<int> myStack; myStack.mypush(1); myStack.mypush(2); myStack.mypush(3); myStack.mypop(); myStack.mypush(4); myStack.mypop(); return 0; }

注:1、原文中的程式輸出錯誤值(很大的負數)!原文程式肯定輸出有誤,參加上面【注】

       2、mypop()方法我做了一下修改,原文程式看起來比較費勁!

       3、【Why!】為什麼編輯的時候顯示的正常,發表之後程式中的紅色字型卻不正常顯示呢??!!!------遇到過好幾次這種情況了!!!