两个栈实现队列
基本原理:
现有两个栈,栈A、栈B。我们都知道栈的顺序的是先进后出,而队列是先进先出。先将数存在A中,再从A读取到B中,用户最终是从B中读取存的数据。比如:要将1-2-3-4-5保存在队列中,那么最终读取的顺序应该也是1-2-3-4-5。先存放在A中,A是栈所以读取的顺序为5-4-3-2-1,5-4-3-2-1又逐一存放在栈B中,所以最终读取顺序就为1-2-3-4-5。
能够导致顺序错误的问题:
- A数据导入B后A中仍有残留数据
这种情况下会导致顺序错乱!
例如:1-2-3-4-5 逐一push进A栈,但是只pop了5-4-3,此时在A栈中还剩下2-1,若此时B栈进行pop或A栈进行push都会发生错误。 - A数据导入B时,B中仍有数据
B栈数据的顺序应高于A栈,但此时A栈pop出一个数,push进B栈,由于栈的特性,刚push进的数的顺序就高于原先存在B栈的数,这显然不合理!
解决顺序错误的问题:
(要实现的方法:add()、poll()、peek())
- 禁止add() 对A、B栈pop操作的权利,若用户需要访问数据,则由poll()、peek()自己将A中数据转移到B。
- B中仍有数据时,禁止A转移数据进B
- B中无数据时,从A转移数据时,必须全部转移,禁止有剩余
实现代码:
import java.util.Stack;
public class A_Queue_Of_Two_Stacks {
//创建两个栈
private static Stack<Integer> stackPush = new Stack<>();
private static Stack<Integer> stackPop = new Stack<>();
//当进行add操作时,先全部存放在stackPush中
// 当想要poll时,检查stackPop中是否还存在数据
// 没有数据的话从stackPush中导入
// 有数据的话那么直接pop
public static void add(int pushNum){
stackPush.push(pushNum);
}
public static int poll(){
//如果stackPop栈中有数据,则直接pop出
if(!stackPop.isEmpty()){
return stackPop.pop();
}else{
//stackPop中无数据时候
// 就需要将stackPush中数据pop出,再push进stackPop
//直到stackPush为空
while (!stackPush.isEmpty()){
int a=stackPush.pop();
stackPop.push(a);
}
return stackPop.pop();
}
}
//peek()与poll()操作可以说完全一样,不再多赘述了
public static int peek(){
if(!stackPop.isEmpty()){
return stackPop.peek();
}else{
while (!stackPush.isEmpty()){
int a=stackPush.pop();
stackPop.push(a);
}
return stackPop.peek();
}
}
public static void main(String[] args){
add(1);
add(2);
add(3);
System.out.println(" 获取队列第一个数 "+peek());
System.out.println("poll 删掉的数为-> "+poll());
System.out.println(" 获取队列第一个数 "+peek());
System.out.println("poll 删掉的数为-> "+poll());
System.out.println(" 获取队列第一个数 "+peek());
add(4);
System.out.println("poll 删掉的数为-> "+poll());
System.out.println("poll 删掉的数为-> "+poll());
}
}
2021.4.16 (我的第一篇博客)