9. 用两个栈实现队列
题目链接
题目描述
用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。
解题思路
in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。
分析
栈的特点是先进后出,而队列的特点是先进先出,主要就是在两个栈中来回倒腾从而实现队列的功能,就好像一个黑盒子,里边是两个栈的操作,但其他人在用这个黑盒子的时候,感觉就像在用队列一样。队列和栈只是逻辑性的数据结构,实现队列和栈可以用数组实现,也可以用链表实现,只要满足队列先进先出,栈先进后出的特性就可以。
用两个栈实现队列,比如一开始在stack1中把a,b,c入栈,想删除虚拟队列的队首元素时,即删除a,但是a在栈底,无法直接删除,所以这个时候就要利用stack2了,在进行删除操作时,可以把stack1中的c,b,a依次弹出并入栈到stack2中,此时a就在stack2的栈顶了,可以直接pop掉。现在b变成stack2的栈顶元素了,继续删除b,直接就可以pop,这就完成了队列的pop操作。那么怎么插入一个新元素呢,比如插入d,那么可以让d直接入栈到stack1。继续删除队列队首元素,从stack2中删除c,然后把d弹出stack1并入栈stack2,然后从stack2中直接pop。通过观察我们发现,如果进行虚拟队列的push操作,可以把元素直接入栈到stack1;如果进行虚拟队列的pop操作,如果stack2为空,那么把stack1中所有的元素弹出并入栈到stack2,然后对stack2进行pop操作;如果stack2不为空,那么直接对stack2进行pop操作,到这里你是不是已经思路变得清晰了。
我们先来用Java的LinkedList链表数据结构来实现链式栈和链式队列,为后面的用两个栈实现队列和用两个队列实现栈来服务。
Java实现栈
package 用两个栈实现队列;/*
作者 :XiangLin
创建时间 :24/02/2020 11:14
文件 :stackDemo.java
IDE :IntelliJ IDEA
*/
import java.util.Iterator;
import java.util.LinkedList;
/**
* 栈
*/
public class stackDemo {
private LinkedList<String> stackList = new LinkedList<>();
/**
* 入栈
*/
public void push(String str){
stackList.addFirst(str);
}
/**
*
*/
public String pop(){
return stackList.removeFirst();
}
/**
* 判断是否为空
*/
public boolean empty(){
return stackList.isEmpty();
}
/**
* 打印栈内所有元素
*/
public void printStack(){
Iterator iterator = stackList.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next() + " ");
}
System.out.println();
}
public static void main(String[] args) {
stackDemo stack = new stackDemo();
System.out.println(stack.empty());
stack.printStack();
stack.push("a");
stack.push("b");
stack.push("c");
System.out.println(stack.empty());
stack.printStack();
}
}
输出:
true
false
c
b
a
Java实现队列
package 用两个栈实现队列;/*
作者 :XiangLin
创建时间 :24/02/2020 11:35
文件 :QueueDemo.java
IDE :IntelliJ IDEA
*/
import java.util.Iterator;
import java.util.LinkedList;
/**
* 队列
*/
public class QueueDemo {
private LinkedList<String> queueList = new LinkedList<String>();
/**
* 入队列
*/
public void push(String str){
queueList.add(str);
}
/**
* 出队列
*/
public String pop(){
return queueList.removeFirst();
}
/**
* 获得队列元素个数
*/
public int getQueueSize(){
return queueList.size();
}
/**
* 判断队列是否为空
*/
public boolean empty(){
return queueList.isEmpty();
}
/**
* 打印队列内所有元素
*/
public void printQueue(){
Iterator iterator = queueList.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next()+" ");
}
System.out.println();
}
public static void main(String[] args) {
QueueDemo queueDemo = new QueueDemo();
queueDemo.push("a");
queueDemo.push("b");
queueDemo.push("c");
System.out.println(queueDemo.queueList.size());
queueDemo.pop();
queueDemo.printQueue();
System.out.println(queueDemo.queueList.size());
}
}
输出:
3
b
c
2
用两个栈实现队列
package 用两个栈实现队列;/*
作者 :XiangLin
创建时间 :24/02/2020 11:54
文件 :TwoStackToQueue.java
IDE :IntelliJ IDEA
*/
/**
* 用两个栈实现队列
*/
public class TwoStackToQueue {
stackDemo stack1 = new stackDemo();
stackDemo stack2 = new stackDemo();
/**
* 入队列
*/
public void push(String str){
stack1.push(str);
}
/**
* 出队列
*/
public String pop(){
if (stack2.empty()){
// 如果栈2为空,就要把栈1所有元素反弹到栈2中
while (!stack1.empty()){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
/**
* 判断新队列是否为空
*/
public boolean empty(){
if(stack1.empty() && stack2.empty()){
return true;
}else {
return false;
}
}
/**
* 打印队列中所有元素
*/
public void printQueue(){
System.out.println("栈1中:");
stack1.printStack();
System.out.println("栈2中:");
stack2.printStack();
}
public static void main(String[] args) {
TwoStackToQueue queue = new TwoStackToQueue();
queue.push("a");
queue.push("b");
queue.push("c");
queue.printQueue();
queue.pop();
queue.printQueue();
}
}
输出:
栈1中:
c
b
a
栈2中:
栈1中:
栈2中:
b
c
个人微信公众号,专注于学习资源、笔记分享,欢迎关注。我们一起成长,一起学习。一直纯真着,善良着,温情地热爱生活。
What you disdained may be the life other people strive for, and the failed life you meant may be what other people have painstakingly earned.
你所嫌弃的,可能是别人拼命想要得到的。你以为失败的人生,也许是别人努力活着的结果。
XiangLin
2020年2月24日于重庆城口
好好学习,天天向上,终有所获