用队列结构实现栈结构
算法思想:
首先栈是先进后出的,而队列是先进先出的。
我们可以借助两个队列实现栈的结构。
1. 所有n个数据进队列A
2. 队A中的前n-1个数据进入队列B
3. 此时队列A中的数据即是最后进队的,将它出队,即是栈的后进先出。
算法实现:
package demo; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; public class TwoQueuesStack { private Queue<Integer> queue; private Queue<Integer> help; public TwoQueuesStack() { queue = new LinkedList<Integer>(); help = new LinkedList<Integer>(); } public void push(int pushInt) { queue.add(pushInt); } public int peek() { //访问栈顶元素 if (queue.isEmpty()) { throw new RuntimeException("Stack is empty!"); } while (queue.size() != 1) { help.add(queue.poll()); //queue队中前n-1个元素放入到help队中 } int res = queue.poll(); help.add(res); swap(); return res; } public int pop() { //出栈 if (queue.isEmpty()) { throw new RuntimeException("Stack is empty!"); } while (queue.size() > 1) { help.add(queue.poll()); } int res = queue.poll(); swap(); return res; } private void swap() { Queue<Integer> tmp = help; help = queue; queue = tmp; } public static void main(String[] args) { TwoQueuesStack stack = new TwoQueuesStack(); stack.push(5); stack.push(4); stack.push(3); stack.push(2); stack.push(1); int res1 = stack.pop(); System.out.println(res1); int res2 = stack.pop(); System.out.println(res2); int res3 = stack.pop(); System.out.println(res3); int res4 = stack.pop(); System.out.println(res4); int res5 = stack.pop(); System.out.println(res5); } }
result: 1 2 3 4 5
用栈实现队列结构
算法思想:
首先栈是先进后出的,而队列是先进先出的。
同理我们可以借助两个栈(一个push栈、一个pop栈)实现队列的结构。
1. push栈中n个数据,倒入pop栈中。
2. pop栈顶元素即是队列的队头元素。
注意:
1)push栈倒数据时要一次倒完,倒数据可发生在任何时候。
2) pop里有数据时,push栈不能倒数据。可以说当push有数据,而pop没有数据时才倒数据。
算法实现:
package demo; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; public class TwoStacksQueue { private Stack<Integer> stackPush; private Stack<Integer> stackPop; public TwoStacksQueue() { stackPush = new Stack<Integer>(); stackPop = new Stack<Integer>(); } public void push(int pushInt) { stackPush.push(pushInt); } public int poll() { if (stackPop.empty() && stackPush.empty()) { throw new RuntimeException("Queue is empty!"); } else if (stackPop.empty()) { //pop栈空才倒 while (!stackPush.empty()) { // 倒数据 stackPop.push(stackPush.pop()); } } return stackPop.pop(); //出队头元素 } public int peek() { if (stackPop.empty() && stackPush.empty()) { throw new RuntimeException("Queue is empty!"); } else if (stackPop.empty()) { while (!stackPush.empty()) { stackPop.push(stackPush.pop()); } } return stackPop.peek(); } public static void main(String[] args) { TwoStacksQueue q = new TwoStacksQueue(); q.push(5); q.push(4); q.push(3); q.push(2); q.push(1); int res1 = q.poll(); System.out.println(res1); int res2 = q.poll(); System.out.println(res2); int res3 = q.poll(); System.out.println(res3); // int res4 = q.poll(); // System.out.println(res4); // // int res5 = q.poll(); // System.out.println(res5); q.push(0); q.push(-1); int res6 = q.poll(); System.out.println(res6); int res7 = q.poll(); System.out.println(res7); } }
小结:
关键在于出栈与出队的设计