用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:
栈的特性是:后进先出,而队列的特性是:先进先出。这里使用两个栈实现队列有点负负得正的意思。
栈1负责添加,而栈2负责删除。
【操作两个“先进后出”的栈实现一个“先进先出”的队列CQueue】---a先进,a先出
用两个栈模拟队列操作:
1)stack1负责入栈,元素{a,b,c}以顺序入栈
2)stack1的元素出栈,以反顺序cba入栈Stack2.此时a在栈顶可以删除
3)b也在stack2的栈顶,也可删除
4)新加一个元素d,压入栈1
5)删除栈2的元素c
即:若Stack2为非空,则它栈顶元素是最先进入队列的元素,可以直接弹出;
若stack2为空时,我们把stack1中的元素逐个弹出并压入stack2[此时先进入队列的元素依然是Stack2的栈顶],又可直接弹出。
import java.util.Stack; public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>(); public void push(int node) { stack1.push(node); //stack1负责添加元素 } public int pop() { while(stack1==null&stack2==null){ System.out.println("this is not a queue"); } while(stack2.isEmpty()){ //若Stack2为空,stack1不为空则把stack1的值弹出并压入stack2 while(!stack1.isEmpty()){ stack2.push(stack1.pop()); } } return stack2.pop(); //直接弹出stack2的值,Stack2负责删除元素 } }
相关题目:两个队列实现一个栈
【操作两个“先进先出”的队列实现一个“先进后出”的栈】----a先进,c先出
1)a,b,c入栈,分别放到队列queue1中,a是队列头部,c是尾部。现在要删除c[则必须把c变成队列头部,把ab放到另一个空的队列中]。
2)从queue1中删除ab,并放到另一个空的队列中,此时可删除queue1中的c
3)同理删除b
4)若新加入一个元素d,将其加入到queue1中的尾部,要删除d则需把queue1中头部删除并插入queue2中,再删除d.
总结:
可以用两个Queue来轮流存储数据,当执行pop,top等指令时,因为要返回Queue中最后一个element,所以把之前的所有elements压到另外一个空queue中,剩下唯一一个element的时候,实现poll返回。依次交替
注意事项:pop,top等取出行为,要先检查两个queue是不是都为空
import java.util.LinkedList; import java.util.Queue; public class MyStack { Queue<Integer> q1 = new LinkedList<Integer>(); Queue<Integer> q2 = new LinkedList<Integer>(); /** Initialize your data structure here. */ public MyStack() { } /** Push element x onto stack. */ public void push(int x) { if (q2.isEmpty()) { //哪个队列有值就将其放入到那个队列中 q1.offer(x); } else q2.offer(x); } /** Removes the element on top of the stack and returns that element. */ public int pop() { while (!q2.isEmpty()) { if (q2.size() == 1) // 如果某队列只有一个元素,将其移除并添加到另一个队列中 return q2.poll(); q1.offer(q2.poll()); } while (!q1.isEmpty()) { if (q1.size() == 1) return q1.poll(); q2.offer(q1.poll()); } return -1; } /** Get the top element. */ public int top() { while (!q2.isEmpty()) { if (q2.size() == 1) { int x = q2.peek(); //得到q2的头部元素 q1.offer(q2.poll()); //移除q2的头部元素放入q1中 return x; } q1.offer(q2.poll()); } while (!q1.isEmpty()) { if (q1.size() == 1) { int x = q1.peek(); q2.offer(q1.poll()); return x; } q2.offer(q1.poll()); } return -1; } /** Returns whether the stack is empty. */ public boolean empty() { return q1.isEmpty() && q2.isEmpty(); } }
关于队列的一些操作的总结:
add 增加一个元素 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列已满,则阻塞
take 移除并返回队列头部的元素