【题9 用两个栈实现队列】
【题目】
用两个栈实现队列,队列的声明如下:请实现它的两个函数appendTail和deleteHead分别完成在队列尾部插入节点和在队列头部删除节点的功能。
[分析]
插入:
向栈stack1 中插入a元素,此时stack1中有元素{a},stack2为空。再像stack1中压入两个元素b和c,此时stack1有元素{a,b,c},c位于栈顶,stack2为空。如图a
删除:
按照队列先入先出原则,最先被删除的应该是a,把stack1中元素逐个弹出并压入stack2中,则元素在stack2中的顺序为{c,b,a},此时弹出stack2的栈顶元素a。stack1为空。以此类推。
再插入一个 元素d。还是压入到stack1中,如图d,考虑下一次删除队列头部stack2不为空,直接弹出它的栈顶元素c,如图e,c的确时比d先进入队列应该在d之前从队列中删除,因此不会出现任何矛盾。
实现
package ti9;
import java.util.Stack;
public class TwoStackImplQueue {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
/*
* 队列的数据压入过程
*/
public void push(Integer element){
stack1.push(element);
}
/*
* 队列的数据弹出过程
*/
public Integer pop(){
if(stack2.size() <= 0){ //第二个栈为空
while(stack1.size() > 0){ //第一个栈不为空
stack2.push(stack1.pop()); //将其第一个栈的数据压入第二个栈中
}
}
if(stack2.isEmpty()){
try{
throw new Exception("queue is empty");
}catch(Exception e){
//e.printStackTrace();
}
}
Integer head = stack2.pop();
return head;
}
public static void main(String[] args) {
TwoStackImplQueue sq = new TwoStackImplQueue();
sq.push(1);
sq.push(3);
sq.push(5);
sq.push(4);
sq.push(2);
System.out.println(sq.pop());
System.out.println(sq.pop());
sq.push(7);
System.out.println(sq.pop());
}
}
【相关题目:用两个队列实现一个栈】
【题目】
通过一系列栈的压入和弹出操作来分析用两个队列模拟一个栈的过程。
分析
(1)先往栈内压入一个元素a:把a插入到两个队列任意一个,如插入queue1中。
(2)往栈内压入b和c:把它们都插入到queue1中。
此时queue1中 有{a,b,c} a位于队列的头部,c位于队列的尾部。
考虑栈的先入先出原则,最后被压入栈的c应该最先被弹出。c位于queue1的尾部,只能 从队列头部删除元素。
(3)从queue1中依次删除a,b并插入queue2。
(4)再从queue1中删除元素c。
相当于从栈中弹出元素c
如图
实现
package ti9;
import java.util.ArrayDeque;
import java.util.Queue;
public class TwoQueueImplStack {
Queue<Integer> queue1 = new ArrayDeque<Integer>();
Queue<Integer> queue2 = new ArrayDeque<Integer>();
/*
* 向栈中压入数据
*/
public void push(Integer element){
//两个队列都为空时,优先考虑 queue1
if(queue1.isEmpty() && queue2.isEmpty()){
queue1.add(element);
return;
}
//如果queue1为空,queue2有数据,直接放入queue2
if(queue1.isEmpty()){
queue2.add(element);
return;
}
//如果queue2为空,queue1有数据,直接放入queue1中
if(queue2.isEmpty()){
queue1.add(element);
return;
}
}
/*
* 从栈中弹出一个数据
*/
public Integer pop(){
//如果两个栈都为空,则没有元素可以弹出,异常
if(queue1.isEmpty() && queue2.isEmpty()){
try{
throw new Exception("satck is empty!");
}catch(Exception e){
e.printStackTrace();
}
}
//如果queue1中没有元素,queue2中有元素,将其queue2中的元素依次放入queue1中,直到最后一个元素,弹出即可
if(queue1.isEmpty()){
while(queue2.size() > 1){
queue1.add(queue2.poll());
}
return queue2.poll();
}
//如果queue2中没有元素,queue1中有元素,将其queue1中的元素依次放入queue2中,直到最后一个元素,弹出即可
if(queue2.isEmpty()){
while(queue1.size() > 1){
queue2.add(queue1.poll());
}
return queue1.poll();
}
return (Integer)null;
}
public static void main(String[] args) {
TwoQueueImplStack qs = new TwoQueueImplStack();
qs.push(2);
qs.push(4);
qs.push(7);
qs.push(5);
System.out.println(qs.pop());
System.out.println(qs.pop());
qs.push(1);
System.out.println(qs.pop());
}
}
参考:
1.《剑指offer》
2.https://blog.csdn.net/super_yc/article/details/75208174