请你用队列实现栈,即用数据结构【队列】来实现数据结构【栈】
提示:之前我们说过,用双向队列来实现栈和队列
也说过用数组来实现栈和队列
还说过用栈来实现队列
(1)栈和队列,双端队列,如何用链表实现双端队列,如何用双端队列实现栈和队列
(2)请你用数组来实现队列和栈(大厂经典面试题)
(3)请你用栈实现队列,即用数据结构【栈】来设计数据结构【队列】
now,用队列来实现栈!
栈与队列的特点
栈:先进后出
队列:先进先出
队列如何实现栈?
首先我们看,外部自然是一个栈:先进的,后出去
(1)内部嘛,自然是俩队列了,一个队列用来做入队,存放着一堆数据,先进来的,排队在前面,左近右出
(2)还有一个队列叫帮队,帮忙的队列,搞啥呢?
如果栈要弹出,那么我们知道,入队中最后进来那个,得先出去,那前面那些呢?
入队前面那些需要转移到帮队中,暂时帮忙存着,然后把最后进来那个数,弹出去
(3)随后尽快把帮队的数又搬移到入队中,保证待会来了新的数,继续排队在最后,出去才能最先出
感觉上,这个搬来搬去的挺复杂,耗时间【但是本题的目的,就是通过设计搞懂队列和栈本质】
我们看例子
push:1 2 3 4
pop:自然就是4,其余的用help队转移一下
弹出4,意味着后进先出了,就是栈的功能
然后将help中的123,又搬回到入队中,保证正常数据排队顺序,方便新数据来的话(比如5),继续排队
下一次要弹出,又去再利用help转移,虽然烦人,但是功能还是实现了的。
(4)然后,这里要注意,访问栈顶的功能,和pop一样,先把前面那些转移到help中,然后访问in中最后进来那个元素
然后,立马将它转移到help中,大家一块再help中排队,否则就乱了哦!!!
之后,才整体从help又搬回去in中。
手撕代码:
//复习:用队列实现栈
public static class Queue2Stack{
//俩队列,入队和帮队
public Queue<Integer> inQueue;
public Queue<Integer> helpQueue;
public Queue2Stack(){
inQueue = new LinkedList<>();//队列
helpQueue = new LinkedList<>();//队列
}
//6个函数--不要记,需要啥就写啥
//判空
public boolean isEmpty(){
return inQueue.isEmpty();//help每次都不会有的
}
//in转移到help中
public void inToHelp(){
if (inQueue.isEmpty()) return;
//有才转移
//如果就1个元素,那就不用转移了,自然后进来的得先出(栈)
if (inQueue.size() == 1) return;
//2个以上就要搬走前面的,剩下最后那个
while (inQueue.size() != 1){
helpQueue.add(inQueue.poll());//转移
}
}
//将help又搬回in中
public void helpToIn(){
//废话不说,直接搬
if (helpQueue.isEmpty()) return;
while (!helpQueue.isEmpty()){
//全搬空
inQueue.add(helpQueue.poll());
}
}
//push
public void push(int value){
//直接放入in屁股排队就行
inQueue.add(value);
}
//pop
public int pop(){
//先转移再弹出,然后再搬回来
if (inQueue.isEmpty()) throw new RuntimeException("没有数!");
inToHelp();//转移
int ans = inQueue.poll();//弹出最后进来那个
helpToIn();//再搬回去
return ans;
}
//peek
public int peek(){
//先转移再弹出,然后再搬回来
if (inQueue.isEmpty()) throw new RuntimeException("没有数!");
inToHelp();//转移
int ans = inQueue.peek();//访问最后进来那个,也就是栈顶
//然后,要把刚刚那个栈顶,也给搬到in中,大家排队,否则就乱了哦!!!这里要注意
helpQueue.add(inQueue.poll());//反正就一个,必然存在的!!!!
helpToIn();//再整体搬回去--这里我复习还能想到,说明基础已经很牢固了。
return ans;
}
}
public static void test3(){
//测试我们的栈
Queue2Stack stack = new Queue2Stack();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
System.out.println(stack.isEmpty());
System.out.println(stack.peek());//4
System.out.println(stack.pop());//也是4
System.out.println(stack.peek());//3
System.out.println(stack.pop());//3
System.out.println(stack.pop());//2
System.out.println(stack.pop());//1
System.out.println(stack.isEmpty());
}
public static void main(String[] args) {
//test2();
test3();
}
结果美滋滋:
false
4
4
3
3
2
1
true
总结
提示:重要经验:
1)栈:先进后出,队列:先进先出
2)用两个栈,可以实现队列,大不了就是让出栈操作之前,将入栈全部转移到出栈中【当然保证出栈为空才能转移】,再从出栈走数,完成先进先出。
3)用两个队列,可以实现栈,大不了就是让帮队用来转移前面先进来那些数,我们只要后进来那个结果,完成后进先出。