思路:由于队列是先进先出的,不论怎么样都无法逆序输出最后一个元素。因此暂时只能想到将第一个队列的除了最后一个元素外的所有值都转移到第二个队列,这样队列1剩下的元素出队就是出栈的元素了。
思路1:q1作为入栈出栈的,q2作为一个中间站,不存储数据
入栈:直接q1入队
出栈:将q1除了最后一个元素外,其他的全部入队到q2中,然后q1剩下的1个元素出队列。之后把q2中的全部元素入队回q1中。
缺点:每弹出一个元素后,数据都要从Q2回到Q1,太浪费时间。
改进思路:由于其中一个队列必然为空的,那就用2个指针来分别指向入栈出栈的队列(pQueue)和作为中间站的队列(pAir),
入栈:pQueue指向的队列入队
出栈:pQueue指向的队列除了最后一个元素外,其他的全部入队到pAir指向的队列中,然后pQueue指向的队列剩下的1个元素出队列。
每次入栈出栈的时候先更新指针指向。
图示(实在找不到图了。又懒画。大概看吧。重点看思路分析):
代码:
package exercise;
/**
* 2个队列实现栈
* 思路:q1作为入栈出栈的,q2作为一个中间站,不存储数据,
* 入栈:直接q1入队
* 出栈:将q1除了最后一个元素外,其他的全部入队到q2中,然后q1剩下的1个元素出队列。之后把q2中的全部元素入队回q1中。
*/
import java.util.LinkedList;
import java.util.Queue;
//q1作为入栈出栈的,q2作为一个中间站,不存储数据
class QueueToStack1<E> {
Queue<E> queue1 = new LinkedList<>();
Queue<E> queue2 = new LinkedList<>();
//入栈
public void push(E e) {
queue1.add(e);
}
//出栈
public E pop(){
E e;
//栈为空判断
if(queue1.isEmpty()) {
throw new RuntimeException("队列为空");
}
//先将q1的元素都转到q2去
while (queue1.size()!=1){
queue2.add(queue1.poll());
}
e=queue1.poll();
//q2元素再回来
while (!queue2.isEmpty()){
queue1.add(queue2.poll());
}
return e;
}
}
class QueueToStack2<E>{
Queue<E> queue1 = new LinkedList<>();
Queue<E> queue2 = new LinkedList<>();
Queue<E> pQueue;//指向入队出队的队列
Queue<E> pAir;//指向中转站队列
//入栈
public void push(E e) {
if(!queue1.isEmpty()){//q1不为空
pQueue=queue1;
pAir=queue2;
}else {
pQueue=queue2;
pAir=queue1;
}
pQueue.add(e);
}
//出栈
public E pop(){
E e;
if(!queue1.isEmpty()){//q1不为空
pQueue=queue1;
pAir=queue2;
}else {
pQueue=queue2;
pAir=queue1;
}
//栈为空判断
if(pQueue.isEmpty()) {
throw new RuntimeException("队列为空");
}
while (pQueue.size()!=1){
pAir.add(pQueue.poll());
}
e = pQueue.poll();
return e;
}
}
github源码:2个队列实现栈
图片来源:https://blog.csdn.net/cherrydreamsover/article/details/80466781