代码编写:用两个栈实现一个队列
栈的特点:
1.后进先出LIFO(Last In First Out)
2.出入元素都是在同一端--栈顶 单开口类比水桶
队列的特点:
1.先进先出FIFO(First In First Out)
2.出入元素在不同的的两端---队头 & 队尾 双开口类比吸管
要求:能画图说明入栈和出栈
栈:
入栈:【栈底】口口口口口口口【栈顶】<---7
出栈:【栈底】口口口口口口口【栈顶】--->7
队列:
入栈:【队头】口口口口口口口【队尾】<---7
出栈:7<---【队头】口口口口口口口【队尾】
思考:单个的栈是不可能实现队列的,两个栈就可以!
方式:组装
一个栈作为队列的入口,负责插入新元素
一个栈负责队列的出口,负责移除老元素
观察:
栈1 【栈底】口口口口口口口【栈顶】<--- 5 4 3 2 1
栈2 【栈底】口口口口口口口【栈顶】---> 1 2 3 4 5
结论:
以栈1出栈的顺序压入栈2,栈2再出栈,即栈1和栈2入栈的顺序是相反的
了解java.util.Stack<E>的API方法:
boolean empty() 测试栈是否为空
E peek() 查看栈顶的元素,不移除
E pop() 移除栈顶的元素,并返回
E push(E item) 元素入栈,在栈顶
int search(Object o) 在栈中查找元素,返回栈顶返回的距离,栈顶为1 底层使用equals方法
代码实现:
import java.util.Stack;
public class TestStackImplQueue {
/**
* 定义两个栈实现队列
* 栈1负责插入新元素
* 栈2负责移除老元素
*/
private Stack<Integer> stack1 = new Stack<Integer>();
private Stack<Integer> stack2 = new Stack<Integer>();
/**
* 入队 即元素压入栈1
*
* @param item
*/
public void inQueue(int item) {
stack1.push(item);
}
/**
* 出队 即元素弹出栈2
*
* @return
*/
public Integer outQueue() {
//最后考虑 栈2为空的情况:栈2为空,栈1还有吗?
if (stack2.empty()) {
if (stack1.empty()) {
return null;
} else {
overTurn();
}
}
return stack2.pop();//E / null
}
/**
* 元素从栈1中出栈,然后压入栈2
* 栈1不为空就一直弹弹弹
*/
private void overTurn() {
while (!stack1.empty()) {
stack2.push(stack1.pop());
}
}
/**
* 入栈是没有问题的,出栈需要考虑是否能拿到全部元素
*/
public static void main(String[] args) {
TestStackImplQueue test = new TestStackImplQueue();
test.inQueue(5);
test.inQueue(4);
test.inQueue(3);
System.out.println(test.outQueue());
System.out.println(test.outQueue());
System.out.println(test.outQueue());
test.inQueue(8);
System.out.println(test.outQueue());
}
}