命题
编写一个类,用两个栈实现队列,支持队列的基本操作 (push、poll、peek)
难度 ♥ ♥ (理解就好...)
设计思路:
- 用两个栈模拟一个队列先进先出的操作
- 必须一次性压入所有的数据到stackPush、stackPop
- 这即是设计思路,同时也是实现的前提条件
做此设计的原因:
假设将栈设计成压入一个值后,立马再弹出一个值,栈相当于只存了一个值的空间(很浪费)又弹出这个值本身,若是栈要存储多个值时,这个思路显得毫无意义可言,本身就是极其错误的思想。
stackPop必须为空,如果不为空stackPush压入数据后将会造成数据顺序的错乱。
设计思路图:
实现
package com.lorem.queue;
import org.junit.Test;
import java.util.Stack;
/**
* @author lorem
* @date 2018/8/22
*/
public class TwoStackQueue {
/**
* 定义两个栈
* 一个先压栈的 stackPush
* 一个弹栈的 stackPop
*/
private Stack<Integer> stackPush;
private Stack<Integer> stackPop;
public TwoStackQueue() {
//之所以不用this,是将两个stack对象合成一个整体的队列
stackPush = new Stack<Integer>();
stackPop = new Stack<Integer>();
}
/**
*
* @param pushInt 添加的测试数据
* 先添加数据到 stackPush
*/
private void add(int pushInt) {
stackPush.push(pushInt);
}
/**
* 如果弹栈 stackPop 为空,且入栈 stackPush 存在值
* 则将stackPush 的存储的所有值弹出压入至stackPop栈中
*/
private void stackPopAdd(){
if (stackPop.empty() && stackPush.empty()) {
//尽早暴露原则
throw new RuntimeException("queue is empty");
} else if (stackPop.empty()) {
while (!stackPush.empty()) {
stackPop.push(stackPush.pop());
}
}
}
/**
* 之后,stackPop再将值弹出
* @return stackPop弹出的值
*/
private int poll() {
stackPopAdd();
return stackPop.pop();
}
/**
* @return 返回栈顶元素
*/
public int peek(){
stackPopAdd();
return stackPop.peek();
}
@Test
public void test(){
TwoStackQueue stackQueue = new TwoStackQueue();
stackQueue.add(1);
stackQueue.add(2);
stackQueue.add(3);
System.out.println(stackQueue.poll());
System.out.println(stackQueue.poll());
System.out.println(stackQueue.poll());
}
}