两个栈模拟一个队列 java_9. 用两个栈实现队列(剑指 Offer 题解Java版)

本文转载自【微信公众号:五角钱的程序员,ID:xianglin965】经微信公众号授权转载,如需转载与原文作者联系

340abff2904bc48af3361b39df1d301a.png

文章目录

9. 用两个栈实现队列题目链接题目描述解题思路分析Java实现栈Java实现队列用两个栈实现队列

9. 用两个栈实现队列

题目链接

牛客网

https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github

题目描述

用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。

解题思路

in栈用来处理入栈(push)操作,out栈用来处理出栈(pop)操作。一个元素进入in栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入out栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。

8d41dbaebbf79ec464c2fbf7caeb3c03.png

分析

栈的特点是先进后出,而队列的特点是先进先出,主要就是在两个栈中来回倒腾从而实现队列的功能,就好像一个黑盒子,里边是两个栈的操作,但其他人在用这个黑盒子的时候,感觉就像在用队列一样。队列和栈只是逻辑性的数据结构,实现队列和栈可以用数组实现,也可以用链表实现,只要满足队列先进先出,栈先进后出的特性就可以。

用两个栈实现队列,比如一开始在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

文件 :stackDemo.java

IDE :IntelliJ IDEA

*/

import java.util.Iterator;

import java.util.LinkedList;

/**

* 栈

*/

public class stackDemo {

private LinkedList 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

文件 :QueueDemo.java

IDE :IntelliJ IDEA

*/

import java.util.Iterator;

import java.util.LinkedList;

/**

* 队列

*/

public class QueueDemo {

private LinkedList queueList = new LinkedList();

/**

* 入队列

*/

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

文件 :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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值