棧的特色是先進後出,而隊列的特色是先進先出。那麼如何用棧來實現隊列呢?算法
先看第一個棧:緩存
1 2 3 4ide
根據先進後出原則,逐個出棧而後存儲到下一個棧:設計
4 3 2 1code
此時,再進行出棧,輸出的將是:blog
4 3 2 1隊列
這和最原始的棧內存「1 2 3 4」的隊列化輸出結果:「4 3 2 1」一致了!也就是,先進來的4元素,也先出去了!圖片
設計兩個棧,第一個棧做爲數據棧用於存儲數據,第二個棧用於反轉順序!內存
對於由兩個棧實現的隊列,若是要返回隊首的時候,就將第一個數據棧把數據都扔給第二個反轉棧用於反轉,隨後就可讓先進來的棧尾元素到達棧首,此時返回棧首其實就是返回隊首!element
須要注意的是:
class MyQueue { private: stack<int> inStk; stack<int> outStk; void turnToStack(stack<int>& inStk, stack<int>& outStk) { while (!outStk.empty()) { inStk.push(outStk.top()); outStk.pop(); } } public: /** Initialize your data structure here. */ MyQueue() { } /** Push element x to the back of queue. */ void push(int x) { inStk.push(x); } /** Removes the element from in front of queue and returns that element. */ int pop() { turnToStack(outStk, inStk); int ret = outStk.top(); outStk.pop(); turnToStack(inStk, outStk); return ret; } /** Get the front element. */ int peek() { turnToStack(outStk, inStk); int ret = outStk.top(); turnToStack(inStk, outStk); return ret; } /** Returns whether the queue is empty. */ bool empty() { return inStk.empty(); } }; /** * Your MyQueue object will be instantiated and called as such: * MyQueue* obj = new MyQueue(); * obj->push(x); * int param_2 = obj->pop(); * int param_3 = obj->peek(); * bool param_4 = obj->empty(); */
爲了能讓隊列實現棧,可否藉助棧實現隊列的思路進行反轉呢?答案是否認的!
由於隊列壓根起不到反轉的效果,因而這裏須要從新設計算法!
對於一個棧:
1 2 3 4
首先輸出的應該是 1 ,由於 1 是最後一個進來的,要先出去!
那麼,先用一個數據隊列存儲棧元素,隊列的元素序列是
1 2 3 4
可是此時的隊首是 4 而不是 1 怎麼辦呢?
再設計一個轉存隊列,用於存儲隊尾前的所有元素,例如:
2 3 4
這時候,數據隊列裏就只有 1 這一個元素了,此時的隊首就是棧首!而後處理完後,再將轉存隊列的內容返回到數據隊列中,由於隊列不會改變次序,因此數據隊列會成爲:
2 3 4
這就是刪除棧首的結果!
設計兩個隊列,一個數據隊列,一個緩存隊列。
第一個數據隊列存儲棧數據,當須要彈棧的時候,將數據隊列除了最後一個元素之外的數據都放到緩存隊列!而後數據隊列就只有一個元素了,就是最後進入的那個元素,就直接彈出便可,此時就實現了 「後進先出」 !
須要注意的是:
class MyStack { private: queue<int> inQue; queue<int> outQue; public: /** Initialize your data structure here. */ MyStack() { } /** Push element x onto stack. */ void push(int x) { inQue.push(x); } /** Removes the element on top of the stack and returns that element. */ int pop() { while (1 != inQue.size()) { outQue.push(inQue.front()); inQue.pop(); } int ret = inQue.front(); inQue.pop(); while (!outQue.empty()) { inQue.push(outQue.front()); outQue.pop(); } return ret; } /** Get the top element. */ int top() { while (1 != inQue.size()) { outQue.push(inQue.front()); inQue.pop(); } int ret = inQue.front(); outQue.push(inQue.front()); inQue.pop(); while (!outQue.empty()) { inQue.push(outQue.front()); outQue.pop(); } return ret; } /** Returns whether the stack is empty. */ bool empty() { return inQue.empty(); } }; /** * Your MyStack object will be instantiated and called as such: * MyStack* obj = new MyStack(); * obj->push(x); * int param_2 = obj->pop(); * int param_3 = obj->top(); * bool param_4 = obj->empty(); */