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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值