Java基础数据结构之队列

一.什么是队列

队列是一种先进先出的数据结构,也就是从左边进从右边出,或者说,只允许在一端插入元素,在另一端删除元素

进行插入操作的一端称为队尾(tail/rear),删除操作的一段称为队头(front/head)。

二.队列的模拟实现

队列应该用链表来存放元素,因为要对头尾进行操作

成员变量:

入队:

首先要判断是否为第一次插入元素,因为要涉及到更新last的值。注意用到了尾插法

出队:

有三种情况,第一种是队列为空,第二种是只有一个元素,第三种是一般状态。注意一般状态下,不要仅仅把first往后移,虽然这样也可以,但最好勤快一点,把前后断的更干净些,不要都交给jvm去做

获取队首元素:

三.队列的使用

队列queue是一个接口

主要使用的就是它的offer方法,poll方法和peek方法

实例化队列对象:

队列的底层是链表,所以实例化队列时一般用LinkedList

有一个问题:能否通过LinkedList中的迭代器来遍历队列?不可以,向上转型的queue访问不到子类独有的方法!!

四.循环队列

循环队列的大小是固定的front表示队头,rear表示队尾,从队尾放元素,每放一个元素,rear就向前移一位,芙蓉厅始终指向第一个元素,出队时front就像前移动

我们可以发现,当队列为空时,rear和front在同一个位置,队列全满时,rear和front也指向同一位置,那怎么判断空与满呢?

1.如何判断空与满

方案一:使用usedsize来记录

方案二:浪费一个空间来表示满

比如数组有9个空,我们只使用8个空,当8个空全都使用上时rear和front就差一步,此时要是再像插入元素,rear就得再往前走,就和front相遇了,说明在放这个元素之前已经把8个空用完了,已经是满的状态了,所以这个元素不能放进去了。

而要是要删除一个元素,front往前走了一步,发现和rear相遇了,就说明空了。

所以说:rear向前走后与front相遇,就是满;front向前走后与rear相遇,就是空

也就是:

队列为空时的条件:rear=front

队列为满时的条件:rear+1=front

但仅仅这样是不对的,假设数组长度为7,现在已经放了6个元素,其实已经满了,此时front=0,rear=6,rear下一步本应是0,但rear+1=7了,不等于0,所以上面的写法不对,而应该为

队列为空时的条件:rear=front

队列为满时的条件:(rear+1)%arr.length=front

方案三:定义一个标记

设置一个flag,初始值为false

当入队时,rear向后移,flag=true;出队时front向后移,flag=false

当队列为空时front=rear并且flag=false(因为最后一步操作肯定是出队)

当队列为满时front=rear并且flag=true(因为最后一步操作肯定是入队)

2.循环队列的代码实现

class MyCircularQueue {
    public int []arr;
    public int front=0;
    public int rear=0;
    public int size;
    public MyCircularQueue(int k) {
        this.arr=new int[k];
    }
    
    public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }
        arr[rear]=value;
        rear=(rear+1)%arr.length;
        size++;
        return true;
    }
    
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }
        front=(front+1)%arr.length;
        size--;
        return true;
    }
    
    public int Front() {
        if(isEmpty()){
            return -1;
        }
        return arr[front];
    }
    
    public int Rear() {
        if(isEmpty()){
            return -1;
        }
        else if(rear==0){
            return arr[arr.length-1];
        }
        else {
            return arr[rear - 1];
        }
    }
    
    public boolean isEmpty() {
        return size==0;
    }
    
    public boolean isFull() {
        return size==arr.length;
    }
}

我这里判断空与满用到的是size

首先enQueue是向队列中插入一个元素,这里就是向队尾插入元素,所以就是在rear下标插入元素,然后rear++,但这样更新rear的值不可以,比如arr.length=7,此时rear指向了6下标,那么rear加1就是7了,就是数组越界了,当rear是6时,表示它已经到了数组末尾,该往回返了,也就是应该到0下标,所以就有了(rear+1)%arr.length。但要判断是否为满。

然后是deQueue,是从队首删除一个元素,直接(front+1)%arr.length即可。还是注意是否空。但注意,要是存放的元素是某个引用类型,就要将front所指位置置为空之后再更新

Front是从队首获取元素,Rear是从队尾获取元素。注意从队尾获取元素的操作。当不为空时,一般情况下只要获取rear-1位置的元素即可,但有一种情况就是rear=0,此时rear-1=-1,下标越界了,所以rear=0时,要获取数组末尾的元素。

五.双端队列(Deque)

双端队列就是允许俩端都可以进行入队和出队操作的队列,Deque是一个接口,其实现类是LinkedList、ArrayDeque、LinkedBlockingDeque。首先LinkedList底层是链表,可以在两头进行插入删除操作,ArrayDeque底层是数组,是顺序表,也可进行。LinkedList最常用。下面是它的一些方法:

把它当队列来用,就建议使用offer,poll,peek这样的方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/432743.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【bug日记】已解决:Invalid bound statement (not found): 找不到对应的Mapper映射类

急着解决问题的哥们直接用目录跳到下文哈 我放传送门了 目录 试错 尝试过确认的东西: 最终解决方案!已经完美解决: 只需要在你配置数据源的地方: 更改为: MybatisSqlSessionFactoryBean sessionFactory …

如何搭建咨询预类小程序?看完快速了解小程序架构

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 今天简单介绍一下咨询预约类小程序,具体功能、系统应用范围。 一、咨询…

安装或卸载VMware时,显示无法打开注册表项,以及开启虚拟机电脑蓝屏重启的解决方法

我之前安装过一次VMware,之后就随手把他删除了,但没有删除干净,最近我再次安装VMware的时候,出现了一系列问题,我决定分享一下我的解决方案。 一:安装或卸载VMware时,显示无法打开注册表项 解决…

微信小程序开发系列(十三)·如何使用iconfont、微信小程序中如何使用字体图标

目录 1. 如何使用iconfont 2. 微信小程序中如何使用字体图标 3. 背景图的使用 1. 如何使用iconfont 在项目中使用到的小图标,一般由公司设计师进行设计,设计好以后上传到阿里巴巴矢量图标库,然后方便程序员来进行使用。 小程序中的字体…

VR智慧商城“场景购”,打造购物新篇章

近日来,“快递新规”引发了社会热议,更有快递员直呼想转行送外卖。现在的快递行业可谓是盛行一时,消费群体逐渐趋于年轻化,很多人一天时间一半时间都在网上冲浪;而对于实体行业来说,如果一味的坚持做线下&a…

git合并多次提交

简介 Git是一个分布式版本控制系统,它允许开发人员在不同的分支上进行并行开发,并将这些分支合并到主分支或其他分支中。在开发过程中,我们经常会创建多个commit来记录每次的代码变更。有时候我们希望将这些连续的commit合并为一个更有意义的…

生成式 AI

生成式 AI 进入应用爆发期,将极大地推动数字化内容生产与创造。 摘要 生成式 AI ( Generative AI 或 AIGC ) 是利用现有文本、音频文件或图像创建 新内容的技术。过去一年,其技术上的 进展主要来自于三大领域:…

理解CPU指令执行:从理论到实践

理解CPU指令执行:从理论到实践 在探讨现代计算机的核心——中央处理单元(CPU)的工作原理时,我们经常遇到“时钟周期”和“指令执行”这两个概念。这些概念不仅对于理解CPU的性能至关重要,而且对于揭示计算机如何处理任…

在三个el-form-item中的el-radio的值中取一个发送给后端怎么获取

问: 请问,这段代码怎么获取:无策略,策略1,策略2的值? 回答: 问: 三个里面只可以选中一个吗? 回答:

LangChain 教程:构建 LLM 支持的应用程序的指南

作者:Aditya Tripathi GPT-4 和 LLaMA 等大型语言模型 (LLM) 在过去几年中创造了一个充满可能性的世界。 它预示着人工智能工具和应用程序的繁荣,ChatGPT 似乎一夜之间成为家喻户晓的名字。 但如果没有为促进新一代应用程序而创建的强大工具和框架&#…

自然语言处理之语言模型(LM)介绍

自然语言处理(Natural Language Processing,NLP)是人工智能(Artificial Intelligence,AI)的一个重要分支,它旨在使计算机能够理解、解释和生成人类语言。在自然语言处理中,语言模型&…

钉钉h5应用 globalthis is not defined vite client

钉钉h5应用 globalthis is not defined vite client problem 背景 钉钉h5应用使用 vue3 vite 构建的前端工程 问题 h5页面在pc端浏览器和pc端钉钉打开正常h5页面在移动端钉钉打开异常 页面空白 通过调试工具找到报错信息 globalthis is not defined vite client reason …

从零开发短视频电商 端到端测试Playwright实战CSDN搜索

文章目录 背景脚本录制配置窗口大小UserAgent设置全局默认超时时间保留登录身份信息加载登录身份信息 测试框架建议 背景 假设我是csdn的测试人员,我想测试如下流程: 1.用户进入站点https://www.csdn.net, 2.在搜索框输入"lakernote&…

Excel技巧:如何对含有相同内容的列增加递增序号

如何在Excel中对含有相同内容的单元格自动添加递增序号 当我们在处理Excel数据时,经常会遇到需要根据某一列中的重复内容来对另一列的单元格进行编号的情况。例如,我们可能需要对所有含有特定字符的单元格进行标记,并在另一列中为它们分配一…

从 Language Model 到 Chat Application:对话接口的设计与实现

作者:网隐 RTP-LLM 是阿里巴巴大模型预测团队开发的大模型推理加速引擎,作为一个高性能的大模型推理解决方案,它已被广泛应用于阿里内部。本文从对话接口的设计出发,介绍了业界常见方案,并分享了 RTP-LLM 团队在此场景…

windows 安装 minio

座右铭:怎么简单怎么来,以实现功能为主。 欢迎大家关注公众号与我交流 1. 打开官网链接 https://www.minio.org.cn/ 2. 点击下载 3. 点击 windows,然后点击 MINIO SERVER 右侧的 DOWNLOAD 进行下载 4. 找到环境变量,新建系统变量…

推荐书籍《低代码平台开发实践:基于React》—— 提升开发效率,构建优质应用

写在前面 随着数字化转型的深入,企业对应用开发效率和灵活性的要求不断提高。低代码平台作为新兴的软件开发方式,通过可视化界面和预构建组件,极大简化了应用开发流程,降低了技术门槛。基于React的低代码平台以其组件化、响应式和…

JavaScript基础3之面向对象关于面向过程、函数式编程、对比、构造函数、原型

JavaScript基础 面向对象面向过程函数式编程命令式编程函数式编程特性副作用透明引用不可变变量函数是一等公民 常见的函数式编程模型 面向对象为什么要使用面向对象封装继承多态 对比面向过程函数式编程面向对象 构造函数原型constructor使用场景 对象原型 面向对象 面向过程…

关于制作Python游戏全过程(汇总1)

目录 前言: 1.plane_sprites模块: 1.1导入模块: 1.1.1pygame:一个用于创建游戏的Python库。 1.1.2random:Python标准库中的一个模块,用于生成随机数。 1.2定义事件代号: 1.2.1ENEMY_EVENT:自定义的敌机出场事件代号&#xf…