当前位置: 首页 > news >正文

代码随想录刷题day29|(栈与队列篇:队列)225.用队列实现栈

目录

一、队列基本知识

二、队列在Java中的实现

1.Queue

2.Deque

①实现普通队列

②实现栈

③实现双端队列

3.基于底层数据结构 

4.组合模式

三、相关算法题目

思路

代码

四、栈和队列总结


一、队列基本知识

队列只能在队尾添加元素,在队头删除元素,因此具有先进先出的特点(FIFO),比如排队,队列只能在首尾两端进行操作,做不到随机访问;

队尾入,队头处

常用操作方法:

入队(enQueue):将元素添加到队列的末尾,如果队列已满,可能会抛出异常或返回错误(取决于实现);

出队(deQueue):在队头移除并返回队列的第一个元素,如果队列为空,可能会抛出异常或者返回错误;

获得队首元素(peek):返回队列的第一个元素,但不移除它,如果队列为空,可能会抛出异常或返回错误;

判空(isEmpty):检查队列是否为空,为空,返回true,不为空,返回false;

获取队列长度(size):返回队列中元素的数量;

二、队列在Java中的实现

1.Queue

Queue是java中实现队列的接口(此处队列指普通队列,FIFO型),实现类有LinkedList(基于双向链表实现)、PriorityQueue(基于堆实现,元素按优先级出队),常用LinkedList;

Queue常用的方法有6个,分为3类:插入、移除、获取元素,每个方法存在两种形式:一种抛出异常(操作失败时),另一种返回一个特殊值(null或false);

操作失败情况抛出异常返回特殊值(null / false)
将元素e插入到队尾超出队列容量boolean  add(E e)bollean  offer(E e):false
获取并移除此队列的头队列为空E  remove()E  poll()null
获取但不移除此队列的头队列为空        E  element()E  peek():null

参考:【Java】Java队列Queue使用详解_java queue-CSDN博客   博主:devnn

2.Deque

Deque 是一个双端队列接口,支持在两端插入和移除元素;继承自Queue接口;

Deque的实现类有ArrayDeque(基于动态数组实现)、LinkedList(基于双向链表实现)、LinkedBlocking Deque;

ArrayDeque在用作队列时快于LinkedList;

Deque有三种用途:普通队列、双端队列、栈,常用方法有12种,不同的数据结构实现选用不同方法;建议最好不要在Deque实现中插入null元素;

①实现普通队列

将元素添加到双端队列的末尾,从双端队列的开头移除元素,得到 FIFO(先进先出)行为

Deque<E> deque = new ArrayDeque<>();

Deque<E> deque = new LinkedList<>();

Queue<E> queue = new ArrayDeque<>();

Queue<E> queue = new LinkedList<>();

常用方法:从 Queue 接口继承的方法完全等效于 Deque 方法

Queue方法等效Deque方法

将指定元素插入Deque末尾

(入队)

抛出异常boolean  add(E e)void  addLast(E e)
返回特殊值bollean  offer(E e)boolean offerLast(E e)
获取并移除Deque第一个元素(出队)抛出异常E  remove()E  removeFirst()
返回特殊值E  poll()E  pollFirst()
获取但不移除Deque第一个元素抛出异常E  element()E  getFirst()
返回特殊值E  peek()E  peekFirst()

示例代码:

Deque<String> deque = new LinkedList<>();//创建一个LinkedList实现类的对象
//Deque<String> deque = new ArrayDeque<>();//创建一个ArrayDeque实现类的对象
deque.addLast("A");
deque.addLast("B");
System.out.println(deque.removeFirst()); // 输出: A

②实现栈

Deque<E> stack = new ArrayDeque<>();

Deque<E> stack = new LinkedList<>();

详见栈 

代码随想录刷题day28|(栈与队列篇:栈)232.用栈实现队列-CSDN博客

③实现双端队列

Deque<E> deque = new ArrayDeque<>();

Deque<E> deque = new LinkedList<>(); 

Queue<E> queue = new ArrayDeque<>();

Queue<E> queue = new LinkedList<>();

注意:Queue接口只能实现队列,Deque接口既能实现队列,也能实现栈;

参考:【Java】Java双端队列Deque使用详解_dequeuejava-CSDN博客

3.基于底层数据结构 

数组:使用循环数组实现

链表:使用单链表实现

了解即可

4.组合模式

原理类似栈,常用LinkedList(底层是链表)实现队列,ArrayList底层是基于动态数组,在ArrayList中,移除第一个元素会导致后面的所有元素向前移动一位,时间复杂度为O(n),如果出队操作频繁,时间开销比较大;

示例代码

import java.util.LinkedList;

public class ComposedQueue<E> {
    private LinkedList<E> list;

    public ComposedQueue() {
        list = new LinkedList<>();
    }

    // 入队
    public void enqueue(E element) {
        list.addLast(element);
    }

    // 出队
    public E dequeue() {
        if (isEmpty()) {
            throw new IllegalStateException("队列为空");
        }
        return list.removeFirst();
    }

    // 查看队首元素
    public E peek() {
        if (isEmpty()) {
            throw new IllegalStateException("队列为空");
        }
        return list.getFirst();
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return list.isEmpty();
    }

    // 获取队列大小
    public int size() {
        return list.size();
    }
}

三、相关算法题目

225.用队列实现栈

思路

关键是出栈操作和获取栈顶元素操作,每次出栈时,将deque1中的元素倒序存入deque2中,原本元素队尾入,想要倒序就让元素从队头入,deque2运行addFirst(x)方法(从队头添加元素,元素顺序和deque1的入队出队顺序一致)即可实现,注意!倒序存入deque2的操作不需要在deque2为空时再操作,举个例子:

按照1 2 3的顺序

首先deque1执行push方法入队,deque1:(队头)1 2 3(队尾),相当于栈的入栈操作

deque2此时为空,将deque1中的元素倒序存入,deque2:3 2 1

deque2从队头出队:3 2 1,实现先进后出,相当于栈的出栈操作;

此时,按照4 5 的顺序再次入队deque1:4 5

如果之前deque2中只出队元素3,还剩元素2 1,此时不为空,假设时在deque2为空才运行addFirst方法,那么此时出栈操作,不会运行该方法,直接从deque2中移除元素,那么将会移除元素2,而在栈中,从栈顶往下应该是:5 4 2 1,应该出栈的是元素5

而每次出队时deque2都执行addFirst操作,此时deque2中:(队头)5 4 2 1(队尾)

出队元素为5,正确

代码

225. 用队列实现栈 - 力扣(LeetCode)

class MyStack {
    //成员变量
     Deque<Integer> deque1;
     Deque<Integer> deque2;
    public MyStack() {
        deque1 = new LinkedList<>();
        deque2 = new LinkedList<>();
    }    
    public void push(int x) {
        //deque1入队
        deque1.addLast(x);
    }    
    public int pop() {
        //deque1出队---倒序入队deque2---deque2出队
        method();
        return deque2.removeFirst();
    }
    public void method(){
        //确保deque2中包含的是deque1中所有元素的倒叙 不用借助数组 deque中有对应方法
        while(!deque1.isEmpty()){
            deque2.addFirst(deque1.removeFirst());
        }
    }
    public int top() {
        method();
        return deque2.getFirst();        
    }    
    public boolean empty() {
        return deque1.isEmpty() && deque2.isEmpty();
    }
}

四、栈和队列总结

java中栈和队列的实现有四种方式:

栈:Stack类、Deque接口、组合模式、底层数据结构(数组、链表)

队列:Queue接口和Deque接口、组合模式、底层数据结构(数组、链表)

其中Deque接口中两个实现类ArrayDeque和LinkedList都可以实现栈和队列,组合模式中通常封装List接口,创建其实现类ArrayList(底层数组)和LinkedList(底层链表)的实例对象,对于栈,常用ArrayList实现,对于队列,常用LinkedList实现;

对于栈,Stack类已经过时,java官方不推荐;

组合模式和底层数据结构的方式均需要手写方法,较为复杂,更推荐使用Deque接口;

相关文章:

  • 数据结构——二叉搜索树
  • npm install 卡在“sill idealTree buildDeps“
  • 图论 之 DFS
  • 计算机视觉算法
  • 当今前沿技术:改变生活的创新趋势
  • HybridCLR+Adressable+Springboot热更
  • 2025易大师C版-运势测算-爱情测算-周易八卦-玄学测算系统源码搭建
  • Spring Cloud微服务入门
  • 深度学习论文: RailYolact -- A Yolact Focused on edge for Real-Time Rail Segmentation
  • 如何使用HttpClinet实现RPC返回对象类型
  • 重学SpringBoot3-整合 Elasticsearch 8.x (二)使用Repository
  • Vue3大文件分片上传,断点续传TS语法(核心思路)
  • 《论大数据处理架构及其应用》审题技巧 - 系统架构设计师
  • Qt常用控件之数字显示控件QLCDNumber
  • 大模型面试|大模型常考面经总结
  • Git 的基本概念和使用方式。
  • Linux 命令大全完整版(08)
  • ai-financial-agent - 为金融投资打造的AI代理
  • Python 中调用 MySQL 数据库的学习文档
  • STM32MP157A单片机移植Linux驱动
  • 网站怎么做图片动态/安徽网站seo
  • 北京市密云区住房和城乡建设委员会网站/网站优化排名公司哪家好
  • 无线网站制作/营销团队外包
  • 酷站网官网/完整的网页设计代码
  • 有哪些做调查问卷赚钱的网站/百度搜索大全
  • 先做网站还是先注册公司/广东深圳今天最新通知