9. 用两个栈实现队列(剑指 Offer 题解Java版)

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日于重庆城口
好好学习,天天向上,终有所获

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值