题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能。
使用两个先进后出的stack去实现一个先进先出的队列,不妨先定义这个队列为CQueue,CQueue包含两个栈stack1和stack2。
预想的步骤如下图所示(绿色文字是这题主要解题思路)
我们可以一步一步来分析:
首先我们调用appendTail压入一个元素{1}时,现在stack1和stack2都没有任何元素,那我们随便往哪个stack中压入都行,比如压入stack1中;再压入两个元素{2}和{3},依然是压入stack1中;
如果说现在要实现弹出一个元素,根据队列的定义我们应该弹出元素{1},但现在元素{1}在stack1栈底。要想弹出元素{1},我们理应先将它上面的元素{2}和元素{3}都移动一下,我们可以将stack1中的元素全部弹出并且放入stack2中,现在元素{1}就在stack2的栈顶了,直接执行stack2.pop()。
如果现在再次压入元素,依然是向stack1里压入;如果要再次弹出元素,则从stack2栈顶弹出。这里值得注意的就是,如果stack2中的元素已经弹出完了,再弹出元素就得判断stack1中是否有元素,如果有元素的话就得把stack1中的元素弹出并压入stack2。
代码实现:
public class doMain09 {
public static void main(String[] args) {
CQueue cQueue = new CQueue();
cQueue.appendTail(1).appendTail(2).appendTail(3); // [3, 2, 1]
cQueue.deleteHead(); // [3, 2]
cQueue.appendTail(4); // [4, 3, 2]
}
}
class CQueue {
private Stack<Integer> stack1;
private Stack<Integer> stack2;
public CQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
public CQueue appendTail(Integer value) {
this.stack1.push(value);
return this;
}
public Integer deleteHead() {
if (stack2.size() == 0) { // 如果stack2中没有元素
if (stack1.size() > 0) {
while (stack1.size() > 0) { // 将stack1中的所有元素弹出,并且压入stack2
Integer value = stack1.pop();
stack2.push(value);
}
} else {
System.out.println("no element in queue, can't pop");
return null;
}
}
return stack2.pop();
}
}