02 Java基本数据结构之队列实现

2023-10-31

系列文章目录

01 Java基本数据结构之栈实现
02 Java基本数据结构之队列实现
03 Java基本数据结构之优先级队列
04 Java基本数据结构之链表


如有错误,还请指出


前言

仍然先简单介绍一下队列的基本结构,然后是整体的代码实现,最后对每个部分需要注意的点作了详细说明。


一、队列(简述)

队列,类似于栈,只是队列中第一个插入的数据项最先被移除(先进先出,FIFO),而在栈中,最后插入的数据项最先移除(LIFO)。
举个例子,可以用于模拟真实世界的环境,例如模拟人们在银行里排队等待,飞机等待起飞,或者网络上数据包等待传送。
在这里插入图片描述

二、栈-数组实现

本次队列实现仍是使用数组实现的,在后面的部分,如理解了链表后,可以使用链表实现。数组实现是一种很简单同时很好理解的方式。

package queue;

/*
* 数组实现的循环队列 有数据项计数字段
* insert : 判断isFull 队尾指针先+1,再插值,到达最大索引时队尾指针则置为-1,接着+1插值
* remove : 判断isEmpty 出队,队头指针+1,出队后队头指针大于最大索引时,队头指针置为0,
* peekFront 查看队头
* isEmpty
* isFull
* size
* */
public class Queue01 {
    private int maxSize; //最大空间
    private long[] queArray; //实现队列的数组
    private int front; //队头指针
    private int rear; //队尾指针
    private int nItems; //已入队的数量

    //构造器
    public Queue01(int maxSize) {
        this.maxSize = maxSize;
        this.queArray = new long[maxSize];
        this.front = 0;
        this.rear = -1; // 插入数据时,rear是先+1再插数据,因此初始化为-1
        this.nItems = 0;
    }
    public void insert(long item) throws Exception {
        if(isFull())throw new Exception("队列满");
        if (rear==maxSize-1) rear=-1;
        queArray[++rear]=item;
        nItems++;
    }
    public long remove() throws Exception {
        if (isEmpty())throw new Exception("队列空");
        long temp=queArray[front++];
        if (front==maxSize) front=0;
        nItems--;
        return temp;
    }
    public long peekFront(){
        return queArray[front];
    }
    public boolean isEmpty(){
        return nItems==0;
    }
    public boolean isFull(){
        return nItems==maxSize;
    }
    public int size(){
        return nItems;
    }

}

三、注意点

3.1 循环队列

队列插入数据时,rear指针向上移动,移向数组下标大的位置。移除数据时,front指针也会向上移动,这样问题是队尾指针很快移动到数组的末端(数组下标最大),但虽然前面有空的单元,由于队尾 rear指针无法移动吗,因此不能插入新数据。

为了避免队列不满却不能插入新数据的问题,可以让队头队尾指针绕回到数组开始的位置,这就是循环队列(又是也称为“缓冲换”)。

3.2构造方法

构造器根据参数规定的容量大小创建一个队列,front 为队头指针,rear为队尾指针,同时使用了一个数据项计数字段 nItems来记录队列里的元素个数。

3.3 insert () 入队

插入操作时 rear(队尾指针)加一后,在队尾指针所指的位置处插入新的数据。但是,当rear指针指向数据的顶端,即maxSize-1位置的时候,在插入数据像之前,必须回绕到数组的底端。回绕操作是把 rear 设置为-1,因此这是 rear 加1后,它等于0,是数组底端的下标值。最后,nItem 加一。

3.4 remove() 出队

出队操作总是由 front 指针得到队头数据项的值,然后 front 加一,但是可能导致 front的值大于数组的顶端(即最大索引),这种情况下 front 就必须回到数组底端。

3.5 peekFront() 查看队列 队头元素

返回front指针所指的数据项的值,有些队列的实现也允许查看队列队尾的值。

3.6 ifFull() isEmpty() 判断空、满

空、满判断在数据结构里是非常重要的,在基本数据结构的实现中,会根据判断结果设计不同的后续处理,在后面的文章中会有所体现。

3.7 数据项计数字段 nItems

另外,isEmpty(),isFull(), size() 这些方法的实现依赖于nItems字段,包含 字段nItems 会使 insert()remove() 方法增加一点额外的操作,因为得分别递增和递减这个变量值。这可能算不上额外的开销,但如果处理大量的入队和出队操作,可能就会影响性能了。

因此一些队列的实现不使用数据项计数的字段,而是通过 front 和 rear 计算出队列是否空满以及插入数据个数,如果这样做,isEmpty(),isFull(), size() 这些方法的实现会比较复杂。

下面是 没有数据项计数字段的队列实现,对于如何通过front rear 指针判断的,可以查看大话数据结构里的队列部分,或者网上查阅,主要理解指针移动后里面的数学关系。

/*
* 数组实现的循环队列 没有数据项计数字段,
* 通过rear 和front的关系计算队列是否为空、满、数据个数
* 注意 isEmpty(),isFull(),size()的复杂性
*  */
public class Queue02 {
    private int maxSize; //最大空间
    private long[] queArray; //实现队列的数组
    private int front; //队头指针
    private int rear; //队尾指针
//    private int nItems;

    //构造器
    public Queue02(int maxSize) {
        this.maxSize = maxSize+1; //数组容量比数据项个数多1
        this.queArray = new long[maxSize];
        this.front = 0;
        this.rear = -1;
    }
    public void insert(long item) throws Exception {
        if(isFull())throw new Exception("队列满");
        if (rear==maxSize-1) rear=-1;
        queArray[++rear]=item;
    }

    public long remove() throws Exception {
        if (isEmpty())throw new Exception("队列空");
        long temp=queArray[front++];
        if (front==maxSize) front=0;
        return temp;
    }
    public long peekFront(){
        return queArray[front];
    }
	// 通过 front 和 rear的数学关系判断
    public boolean isEmpty(){
        return rear+1==front||front+maxSize-1==rear;
    }
    public boolean isFull(){
        return rear+2==front||front+maxSize-2==rear;
    }
    public int size(){
        if (rear>=front)
            return rear-front+1;
        else
            return (maxSize-front)+(rear+1);
    }

}

测试

public class QueueTest {
    public static void main(String[] args) throws Exception {
        System.out.println("数组实现的循环队列 有数据项计数字段");
        Queue01 theQueue=new Queue01(5);
        theQueue.insert(10);
        theQueue.insert(20);
        theQueue.insert(30);
        theQueue.insert(40);
        theQueue.insert(50);
        System.out.println(theQueue.peekFront());
        System.out.println(theQueue.remove());
        System.out.println(theQueue.remove());
    }
}

/*
数组实现的循环队列 有数据项计数字段
10
10
20
 */
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

02 Java基本数据结构之队列实现 的相关文章

随机推荐

  • 服务器信号MBR,[讨论]Windows启动过程(MBR分析)

    讨论 Windows启动过程 MBR分析 2013 9 17 13 33 12376 讨论 Windows启动过程 MBR分析 2013 9 17 13 33 12376 此处我分析系统操作系统加载前的事 从按开机键开始 有心人一起讨论下
  • tomcat源码分析连接coyote catalina

    http blog csdn net aesop wubo article details 7630440 http blog csdn net cutesource article details 5091732
  • java服务器调试指南

    在实际开发中 总会遇到程序启动不起来或者运行结果不符合期望的情况 如果是在本地 直接debug就行了 几乎人人都会 但是如果到了远程 大多数情况下我们可以看日志 通过日志排查定位到问题 但是如果你的日志不多 或者日志中看不出问题 此时情况就
  • 图像识别流程学习总结

    通过图像识别的学习 初步总结了图像识别的流程及归类 希望可以帮到正在学习的小伙伴 一 前期准备工作 1 数据集的获取 在进行数据分析之前需要有数据进行识别 这里所谓的数据指的是图像 我们需要对需要识别的图像分好其类别才能更好的调用 下面以天
  • 【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL移植

    一 环境介绍 RK3588主板搭载Android12操作系统 内核是Linux5 10 使用ST的六轴传感器LSM6DSR芯片 二 芯片介绍 LSM6DSR是一款加速度和角速度 陀螺仪 六轴传感器 还内置了一个温度传感器 该芯片可以选择I2
  • Unity中如何跟随某个物体运动浅谈

    跟随某个物体 具体哪个轴 或完全跟随 运动详解 跟随某个物体移动 使用方式 1 如果勾选x轴就只跟随那个物体的x轴移动 2 如果勾选x和y轴就只跟随那个物体的x和y轴移动 3 如果全勾选就跟随那个物体移动 都不勾选就都不跟随 代码比较简单
  • Ubuntu下 IDEA安装和使用教程

    1 去官方下载IDEA http www jetbrains com idea ultimate版本和community版本其实都差不多 够用了 建议学生可以下载最终版 然后用教育邮箱登录 这样可以免费哦 我准备把它解压到 usr loca
  • 【图解RabbitMQ-5】RabbitMQ Web管控台图文介绍

    作者名称 DaenCode 作者简介 CSDN实力新星 后端开发两年经验 曾担任甲方技术代表 业余独自创办智源恩创网络科技工作室 会点点Java相关技术栈 帆软报表 低代码平台快速开发 技术尚浅 闭关学习中 人生感悟 尝尽人生百味 方知世间
  • python三方模块nltk

    nltk Natural Language Toolkit 是一个Python第三方模块 用于处理自然语言处理 NLP 任务 它提供了许多工具和数据集 可以帮助开发人员对自然语言文本进行分词 词性标注 句法分析 语义分析 语料库管理等操作
  • JAVA开发:前端+后端面试题

    一 java基础面试题 1 JDK和JRE有什么区别 JRE Java Runtime Environment java 运行时环境 即java程序的运行时环境 包含了 java 虚拟机 java基础类库 JDK Java Developm
  • 合并二叉树

    将这两棵树合并成一棵新二叉树 合并的规则是 如果两个节点重叠 那么将这两个节点的值相加作为合并后节点的新值 否则 不为NULL的节点将直接作为新二叉树的节点 方法1 使用递归 递归三部曲 1 参数和返回值 参数为两个二叉树的根结点 返回值为
  • 学计算机买电脑显卡1605ti够吗,GTX1650和GTX1050Ti哪个好?GTX1050ti和GTX1650性能差距对比评测...

    GTX1650显卡在2019年4月22日进行发售 不少用户认为GTX1650是智商检测卡 真的是吗 从命名上来看 GTX1650应该是GTX1050的升级产品 不过根据英伟达的说法 GTX1650相比GTX1050提升幅度达到了70 但是相
  • HTML5 Web Worker深入浅出教程

    HTML5 Web Worker简介 至 2008 年 W3C 制定出第一个 HTML5 草案开始 HTML5 承载了越来越多崭新的特性和功能 它不但强化了 Web 系统或网页的表现性能 而且还增加了对本地数据库等 Web 应用功能的支持
  • 机器学习评估方法——P值校验

    目标 假设在 0 05的情况下 根据舆情监测项目需求 查看召回率和准确率的置信区间 均值 过程 1 输入数据 三列分别是precision recall f1 score 每一列分别计算 以此为例 一共四十行 即样本容量为40 2 计算标准
  • linux下登陆mysql失败

    一 提示由于没有密码 拒绝登陆 ERROR 1045 28000 Access denied for user root localhost using password NO 1 关闭mysql service mysqld stop2
  • mysql索引之B+树

    1 概述 提到B 树就不得不提及二叉树 平衡二叉树和B树这三种数据结构了 B 树就是从他们三个演化来的 众所周知B 树是一种常见的数据结构 被广泛应用于数据库和文件系统等领域 B 树的设计目标是保持树的平衡性 以提供稳定的性能 并且适用于大
  • 链表插入详解

    单链表速成 增与删 众所周知 链表是数据结构的重中之重 但有许多朋友对此并不感冒 甚至想骂 本文主要介绍小编对于链表的喜与悲 乐于忧 先上图 添加结点 单链表结点类型声明 typedef int ElemType 假设ElemType为自定
  • python捕获异常时,打印异常的类型、报错文件、与报错所在的行

    捕获异常 异常的完整代码是 try raise Exception wa except print 报错 else print 没有报错 finally print 程序关闭 得到结果 报错 程序关闭 一般程序里的 try与except是一
  • 如何优化一个肽预测模型

    要优化一个肽预测模型 首先需要考虑的是输入数据的质量 确保输入的数据是完整的 正确的 而不是噪声数据 此外 还需要考虑模型的训练方式 比如是否使用正则化和提前停止来确保不会过拟合训练数据 最后 应该尝试在模型中使用不同的参数来改善模型的性能
  • 02 Java基本数据结构之队列实现

    系列文章目录 01 Java基本数据结构之栈实现 02 Java基本数据结构之队列实现 03 Java基本数据结构之优先级队列 04 Java基本数据结构之链表 如有错误 还请指出 文章目录 系列文章目录 前言 一 队列 简述 二 栈 数组