一、需求
-
用两个栈实现一个队列。
-
队列的声明如下,实现它的两个函数 appendTail 和 deleteHead,完成在队列尾部插入整数和在队列头部删除整数的功能。
-
若队列中没有元素,deleteHead 操作返回 -1。
二、思路分析
- 队列的特点为先进先出,栈的特点为先进后出;
- 现在有两个栈,栈1和栈2,将1,2,3,4,5入栈1,然后依次出栈到栈2,那么栈2中自栈顶到栈底元素为1,2,3,4,5,将栈2中元素出栈的顺序为1,2,3,4,5,这样通过利用两个栈,实现了队列的特点"先进先出";
- 定义两个Stack集合,并在给定构造方法中初始化,添加元素就不用说了;
- 关于删除元素,如果栈1和栈2均为空,那么返回-1,如果栈2为空,栈1不为空,那么将栈1中所有元素弹出至栈2,若栈2不为空,那么直接将栈2元素弹出。
三、代码实现
class CQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
public CQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
public void appendTail(int value) {
stack1.push(value);
}
public int deleteHead() {
if(stack1.size() == 0 && stack2.size() == 0) {
return -1;
}
if(stack2.size() <= 0) {
while(stack1.size() != 0) {
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
四、对代码的优化
- Stack继承了Vector接口,Vector底层是一个Object[ ]数组,需要考虑空间扩容和移位的问题,效率比较低;
- 使用LinkedList来实现栈的操作,其本身是一个双向链表,扩容较少,效率较高。
代码是这样的:
class CQueue {
LinkedList<Integer> stack1;
LinkedList<Integer> stack2;
public CQueue() {
stack1 = new LinkedList<>();
stack2 = new LinkedList<>();
}
public void appendTail(int value) {
stack1.add(value);
}
public int deleteHead() {
if(stack1.isEmpty() && stack2.isEmpty()) {
return -1;
}
if(stack2.isEmpty()) {
while(!stack1.isEmpty()) {
stack2.add(stack1.pop());
}
}
return stack2.pop();
}
}