用兩個佇列實現一個棧
阿新 • • 發佈:2019-01-11
題目:
說明如何用兩個佇列來實現一個棧,並分析有關棧操作的執行時間。
解法:
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!】為什麼編輯的時候顯示的正常,發表之後程式中的紅色字型卻不正常顯示呢??!!!------遇到過好幾次這種情況了!!!