用两个队列实现栈和用两个栈实现队列
首先是用两个栈实现队列代码如下:
class Solution {//队列是先进先出,栈是后进先出。这个要实现主要要解决的问题是队列的先进先出并且是可以同时进出数据要用两个栈来实现, //我们可以把stack1作为缓存栈,stack2作为输出栈,把队列的数据一直存入入栈stack1直到遇到pop操作后我们可以就可以把数据取出再存到stack2中, //然后我们根据pop的数量取出相应数量的数据,取完继续往stack1存入数据,当再次遇到pop操作时若是stack2栈未空则继续取出数据, //若是为空则把stack1中的数据存入stack2中 //其实总的来说就是用两个栈把数据做了两次逆转 public: void push(int node) { stack1.push(node);//先把数据存入stack1中 } int pop() { int temp; if(stack2.empty())//如果栈stack2空则把栈stack1中的数据存到stack2中 { while(!stack1.empty()) { //temp=stack1.top(); stack2.push(stack1.top()); stack1.pop(); } } temp=stack2.top();//如果要把stack1中的数据存到栈stack2时stack2非空则要先把stack2中的数据全部取出后才可以再次存入, //不然会使得前面存入的数据在后存入的数据的栈下面的位置,根据栈的存取规则则不能实现队列的存取操作 stack2.pop(); return temp; } private: stack<int> stack1; stack<int> stack2; };
接下来是用两个队列实现栈
如图所示,我们先往栈内压入一个元素a。由于两个队列现在都是空,我们可以选择把a插入两个队列中的任一个。我们不妨把a插入queue1。接下来继续网栈内压入b,c两个元素。我们把它们都插入queue1。这个时候 queue1包含3个元素a,b,c其中a位于队列的头部,c位于队列的尾部。
现在我们考虑从栈内弹出一个元素。根据栈的后入先出的原则,最后被压入栈的c应该最先被弹出。由于c位于queue1的尾部,而我们每次只能从队列的头部删除元素,因此我们可以从queueu中依次删除a/b/c并插入到queue2中,再从queue1中删除c。这就相当于从栈中弹出元素c了。我们可以用同样的方法从栈内弹出元素b。
接下来我们考虑从栈内压入一个元素d.此时queue1已经有了一个元素,我们就把d插入到queue1的尾部。如果我们再从栈内弹出一个元素,此时被弹出的应该是最后被压入的d.由于d位于queue1的尾部,我们只能先从头部删除 queue1的元素并插入到queue2,直到queue1中遇到d再直接把它删除。如果所示:
代码如下:
class MyStack { public: queue<int> q1,q2; /** Initialize your data structure here. */ MyStack() { } /** Push element x onto stack. */ void push(int x) { while(!q2.empty()) { q1.push(q2.front()); q2.pop(); } q2.push(x); while(!q1.empty()) { q2.push(q1.front()); q1.pop(); } } /** Removes the element on top of the stack and returns that element. */ int pop() { int a = q2.front(); q2.pop(); return a; } /** Get the top element. */ int top() { return q2.front(); } /** Returns whether the stack is empty. */ bool empty() { return q2.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(); */