棧和隊列數據結構的相互實現[LeetCode]
棧是先進後出,隊列是先進後出,這裏討論一下兩種數據結構之間的相互實現。
一.用兩個棧實現隊列
我們用一個棧來實現隊列的進隊操作(棧A),用另一個棧來實現隊列的出隊操作(棧B)。
1.入隊列:
把元素放進棧A即可。假如棧A已滿並且棧B為空,可以先把棧A中的所有元素先彈出並放入棧B中;假如棧B不為空,則出錯了(不能插入)。
2.出隊列:
假如棧B不為空,直接彈出。假如棧B為空,由於隊列是先進先出的,因此要出隊列時,我們要先把棧A中的元素全部放進棧B中,然後再從棧B中彈出棧頂元素。
3.例子:
進行以下操作:
(1)插入1:
棧A:1
棧B:空
(2)插入2(左邊為棧頂):
棧A:2 1
棧B:空
(3)出隊列:
棧B為空,先把棧A的元素彈出插入棧B:
棧A:空
棧B:1 2
棧B彈出:
棧A:空
棧B:2
(4)出隊列
棧B不為空,直接彈出:
棧A:空
棧B:空
這樣,進隊列的順序為1 2,出隊列的順序為1 2,滿足隊列的特性。
4.LeetCode相關題目
232. Implement Queue using Stacks(https://leetcode.com/problems/implement-queue-using-stacks/description/):
這道題的考慮的東西很少,沒考慮一些特殊情況:
#include <iostream> #include <stack> usingnamespace std; class MyQueue { public: stack<int> in; stack<int> out; /** Initialize your data structure here. */ MyQueue() { } /** Push element x to the back of queue. */ void push(int x) { in.push(x); } /** Removes the element from in front of queue and returns that element.*/ int pop() { if (!out.empty()) { int temp = out.top(); out.pop(); return temp; } else { if (in.empty()) { return -1; } else { while (!in.empty()) { out.push(in.top()); in.pop(); } int temp = out.top(); out.pop(); return temp; } } } /** Get the front element. */ int peek() { if (!out.empty()) { return out.top(); } else { if (in.empty()) { return -1; } else { while (!in.empty()) { out.push(in.top()); in.pop(); } return out.top(); } } } /** Returns whether the queue is empty. */ bool empty() { return in.empty() && out.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.用隊列實現棧有兩種方法,兩種方法的入棧和出棧的時間復雜度不相同,按需使用:
假設有兩個隊列,一個隊列A,不為空,一個隊列B,為空。隊列A中的元素符合棧操作的前提。
(1)入棧O(n),出棧(1)
入棧時,直接把元素放進空的隊列B,然後把隊列A所有的元素按順序放到隊列B中。隊列A就變為空了。此時,最後一個“入棧”的元素就成了隊列頭,需要彈出直接從隊列B中彈出即可。這樣就滿足了棧後進先出的特性了。之後的操作兩個隊列交替就行了。
(2)入棧O(1),出棧(n)
入棧時,直接把元素放進不為空的隊列A的隊尾;出棧時,把棧A的前n-1個元素放入棧B中,棧A中剩下一個的元素就是最新插入的元素,直接出隊列,也滿足棧的特性了。
2.LeetCode相關題目
225. Implement Stack using Queues(https://leetcode.com/problems/implement-stack-using-queues/description/)
這道題用第(1)種方法會快一點,說明出棧操作多一點吧。
方法(1):
class MyStack { public: /** Initialize your data structure here. */ queue<int> a; queue<int> b; MyStack() { } /** Push element x onto stack. */ void push(int x) { if (a.empty() && b.empty()) { a.push(x); return; } if (a.empty()) { a.push(x); while (!b.empty()) { a.push(b.front()); b.pop(); } } else { b.push(x); while (!a.empty()) { b.push(a.front()); a.pop(); } } } /** Removes the element on top of the stack and returns that element. */ int pop() { if (a.empty()) { int temp = b.front(); b.pop(); return temp; } else { int temp = a.front(); a.pop(); return temp; } } /** Get the top element. */ int top() { return a.empty() ? b.front() : a.front(); } /** Returns whether the stack is empty. */ bool empty() { return a.empty() && b.empty(); } };
方法(2):
class MyStack { public: /** Initialize your data structure here. */ queue<int> a; queue<int> b; MyStack() { } /** Push element x onto stack. */ void push(int x) { if (a.empty() && b.empty()) { a.push(x); return; } if (!a.empty()) { a.push(x); } if (!b.empty()) { b.push(x); } } /** Removes the element on top of the stack and returns that element. */ int pop() { if (!a.empty()) { while (a.size() != 1) { b.push(a.front()); a.pop(); } int temp = a.front(); a.pop(); return temp; } else { while (b.size() != 1) { a.push(b.front()); b.pop(); } int temp = b.front(); b.pop(); return temp; } } /** Get the top element. */ int top() { if (!a.empty()) { while (a.size() != 1) { b.push(a.front()); a.pop(); } int temp = a.front(); b.push(a.front()); a.pop(); return temp; } else { while (b.size() != 1) { a.push(b.front()); b.pop(); } int temp = b.front(); a.push(b.front()); b.pop(); return temp; } } /** Returns whether the stack is empty. */ bool empty() { return a.empty() && b.empty(); } };
棧和隊列數據結構的相互實現[LeetCode]