兩個佇列模擬乙個棧

2021-07-05 11:03:17 字數 1338 閱讀 7776

上文給出了兩個棧模擬乙個佇列的解法,本文繼續解決兩個佇列模擬乙個棧的問題。

先進先出變成先進後出,乍一想可能覺得不可能。但是這道題的前提是用兩個佇列,我們完全可以用其中乙個佇列queue1儲存好要出棧的元素,每當有新元素要入棧的時候就把他加到queue1中。怎麼讓queue1中的元素按出棧順序排列呢,即怎麼把進入到佇列中的元素反轉過來呢?這時候queue2派上了用場。

思路1:

利用乙個指標指向其中乙個空佇列,這個空佇列用來入棧;另外需要一指標指向另乙個佇列,用於出棧。有新元素要入棧時的操作:將新元素加入到空佇列中,若另乙個佇列不為空,則把另乙個佇列中的元素轉移到剛剛入棧的空佇列中,最後交換兩個指標的指向;出棧時的操作很簡單,直接根據出棧佇列的指標找到出棧佇列,從佇列中取出第乙個元素即為出棧,別忽略了邊界情況判斷。

比如,12345入棧的過程如下圖所示:

如果把佇列比喻成兩兩根管子,元素比喻成小球。則上面的思路總結起來就是:總是把新的小球放到空管裡,它自然會下沉到管子的最下面,然後把另一根管子裡的小球順到這個管子裡來。需要拿出小球的時候,就找到有小球的管子,把最下面的小球放出來。

思路2:

用乙個指標指向乙個佇列用於出棧和入棧。入棧時直接將元素加入到佇列中;出棧時,把佇列中除最後加入的元素外全部轉移到另乙個佇列中。這樣最後加入的元素自然可以出棧。以12345入棧再順序出棧為例,下圖中**1為入棧後的狀態。面的**分別為2345出棧過程,元素轉移後出棧前的狀態

上面兩種思路的不同點在於翻轉元素順序的操作在入棧時還是在出棧時。但是,都有乙個侷限,棧的容量等於其中容量最小的佇列的容量。相較於棧,佇列的出隊入隊操作分別在兩端,這裡可以利用這個特點進行優化。

思路3:

模擬乙個棧非得用兩個佇列嗎?棧中的元素出棧後,再入棧的話,還是在原來的位置;佇列中的元素則可以出隊再入隊實現從佇列頭部到佇列尾部的轉移,而且把佇列看成乙個迴圈的序列的話,它還是有序的,只要我們還能找得到它的頭和尾。對於兩個佇列,仍然可以首尾相接形成乙個環。我們只需要遵循下面兩個原則即可,出棧時旋轉序列,使得要出棧的元素位於佇列的頭部,然後從佇列中取出;入棧時旋轉序列,使得序列的尾部正好出現在佇列的尾部,並且有空間可以加入新元素,然後新元素加入佇列。以1234567入棧,然後7出棧為例,下圖第乙個表為12345入棧後的狀態,第二個和第三個表分別為6、7入棧後的狀態,最後乙個表為7出棧前的狀態。

兩個棧模擬乙個佇列 兩個佇列模擬乙個棧

解題思路 插入操作在stack1中進行,刪除操作在stack2中進行,如果stack2為空,則將stack1中的所有元素轉移到stack2中。include include includeusing namespace std template class cqueue 建構函式 template ...

兩個棧模擬乙個佇列

兩個棧模擬乙個佇列,1號棧為入隊,棧頂表示隊尾 2號棧為出隊,棧頂表示隊首。入隊,直接進1號棧 出隊,先判斷2號棧是否有元素,有元素就直接彈出棧頂即隊首,如果2號棧沒有元素,則將1號棧的元素順序彈出並進2號棧。cpp view plain copy include include include u...

兩個棧模擬乙個佇列

利用兩個棧s1和s2模擬乙個佇列,當需要向佇列插入乙個元素時,用來是s1來存放那個已輸入的元素,即s1執行入棧操作。當需要出隊時,則對s2執行出棧操作。由於從棧中取出元素的順序是原順序的逆序,所以必須將s1中的所有元素全部出棧併入棧s2中,再對s2執行出棧操作,完成出隊操作。define elemt...