常见的一个面试题,就是栈和队列的转换问题,先来说一下原理:
如何通过栈实现队列?
栈是先进后出,队列是先进先出,所以准备两个栈,一个按照正常入栈顺序入栈,然后再出栈到第二个栈中,这样顺序就反过来了。看图:
按照队列的入队顺序应该是:1,2,3,出队顺序应该是1,2,3(先进先出)
入栈序列:1,2,3,把栈内所有数字全部弹出依次入栈B,栈B出栈顺序为:1,2,3
这样就通过栈实现了队列
需要注意的是:如果栈B中有元素,则栈A不能往B中压入元素,否则会造成乱序,必须B栈没有元素了,栈A再全部将元素压入栈B中。
如何通过队列实现栈
这个思路也很容易,首先准备两个队列,因为队列先进先出的原因,所以准备一个A队列,依次存入元素,需要执行弹出任务的时候,就把前面先入列的元素依次入B队,A队剩下的元素弹出,然后再重复这个过程就可以像栈那样先进后出,后进先出了,看图:
队列A入队顺序为:1,2,3,然后把先入队的两个元素依次弹出,只留下一个元素,
然后互换两个队列的名字,再执行相同流程,把Q:B中的先入队元素1弹出放到Q:A中,弹出Q:B中元素,再按照此过程弹出1:
思路比较简单,直接上代码:
package Mianshi;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class Stack_And_Queue_Convert {
public static class TwoStackQueue{
Stack<Integer> data;
Stack<Integer> help;
public TwoStackQueue() {
this.data = new Stack<>();
this.help = new Stack<>();
}
public void push(int num) {
data.add(num);
if(this.help.empty()) {
help.add(data.pop());
}
}
public int pop() {
if(this.help.empty()) {
if (this.data.empty())
throw new RuntimeException("the queue is empty!");
else
while (this.data.size() > 0) {
this.help.add(this.data.pop());
}
}
int value = help.pop();
return value;
}
public int peek() {
if (help.empty()) {
if (this.data.empty())
throw new RuntimeException("the queue is empty!");
else
while (this.data.size()>=0)
this.help.add(this.data.pop());
}
int value = this.help.pop();
this.help.add(value);
return value;
}
}
//通过两个队列实现栈结构
public static class TwoQueueStack{
Queue<Integer> data;//永远让data队列转移数字并且弹出剩下的最后元素
Queue<Integer> help;//就是一个辅助队列
public TwoQueueStack() {
data = new LinkedList<>();
help = new LinkedList<>();
}
//压入元素
public void push(int num) {
data.add(num);
}
//弹出元素
public int pop() {
//data数组为空则没法弹出
if (data.isEmpty())
throw new RuntimeException("Stack is empty!");
//队列中只留最后入列的元素
while (data.size() > 1) {
help.add(this.data.poll());
}
int value = this.data.poll();
//让help队列和data队列互换
swap();
return value;
}
//让执行完弹出任务的空data队列变成help队列,刚才作为help的队列变成data
private void swap() {
Queue<Integer> tmp = help;
help = data;
data = tmp;
}
}
public static void main(String[] args) {
Stack_And_Queue_Convert.TwoQueueStack stack = new TwoQueueStack();
stack.push(30);
stack.push(20);
int value = stack.pop();
System.out.println("pop1 = "+value);
value = stack.pop();
System.out.println("pop2 = "+value);
System.out.println("=================================================");
Stack_And_Queue_Convert.TwoStackQueue queue = new TwoStackQueue();
queue.push(11);
queue.push(13);
queue.push(16);
int num = 0;
num = queue.peek();
System.out.println("peek: " + num);
num = queue.peek();
System.out.println("peek: " + num);
num = queue.pop();
System.out.println(num+" has been pop!");
num = queue.pop();
System.out.println(num+" has been pop!");
num = queue.pop();
System.out.println(num+" has been pop!");
}
}
执行结果:
pop1 = 20
pop2 = 30
=================================================
peek: 11
peek: 11
11 has been pop!
13 has been pop!
16 has been pop!
Process finished with exit code 0