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

日撸Java三百行(day17:链队列)

目录

一、队列基础知识

1.队列的概念

2.队列的实现

二、代码实现

1.链队列创建

2.链队列遍历

3.入队

4.出队

5.数据测试

6.完整的程序代码

总结


一、队列基础知识

1.队列的概念

今天我们继续学习另一个常见的数据结构——队列。和栈一样,队列也是一种操作受限制的线性表,其限定在表的前端进行删除操作,在表的后端进行插入操作,删除这一端叫做队头,插入这一端叫做队尾。由于队列属于线性表的范畴,所以队列当然拥有线性表存储数据的特性,其中队列存储的数据元素称为队列元素。注意,当队列中没有数据元素时,为空队列。

在之前,我们说过栈是一种先进后出(后进先出)的线性表,而队列却完全不一样。因为队列只能在队头删除,在队尾插入,所以最先进入的元素会最早到达队头然后被删除,因此队列是一种先进先出(后进后出)的线性表。这其实有点像我们平时在电影院排队买票,第一个排队的人就最先到达队头买票,最后一个排队的人只能最晚到达队头买票。

和顺序表、链表、栈这些线性表一样,队列也有一些基本操作实现,这里我们主要介绍的是入队和出队。

  • 入队:在队列中插入一个队列元素就叫做入队
  • 出队:在队列中删除一个队列元素就叫做出队

2.队列的实现

在java中,队列的实现可以通过以下两种方式完成。

  • 顺序队列:以数组为底层,通过顺序存储结构实现队列。分配一段连续的存储空间,用两个整型下标front和rear分别代表队头和队尾。

  • 链队列:以链表为底层,通过链表存储结构来实现队列。链队列类似于一个单链表,用头指针header和尾指针tail分别指向队头和队尾。

二、代码实现

这里我们采用链队列进行模拟。

1.链队列创建

由于链队列基于链表结构,所以它的创建大体上和链表差不多,结合之前学过的链表知识可以很容易得到如下代码:

第一步,我们同样创建一个内部类Node作为结点类,并在其中定义成员变量data域和next域,以及一个基本成员方法。

public class LinkedQueue {/*** An inner class.*/class Node {/*** The data.*/int data;/*** The reference to the next node.*/Node next;/********************* * The constructor.* * @param paraValue The data.******************* */public Node(int paraValue) {data = paraValue;next = null;}// Of the constructor}// Of class Node

第二步,为了方便后续进行出队入队操作,我们提前准备一个头指针header和一个尾指针tail,并通过new关键字为其分配内存空间。

   /*** The header of the queue.*/Node header;/*** The tail of the queue.*/Node tail;/************************ Construct an empty sequential list.**********************/public LinkedQueue() {header = new Node(-1);// header.next = null;tail = header;}// Of the first constructor

2.链队列遍历

链队列的遍历我们同样通过重写toString()方法来完成,如下:

    /************************ Overrides the method claimed in Object, the superclass of any class.**********************/public String toString() {String resultString = "";if (header.next == null) {return "empty";} // Of ifNode tempNode = header.next;while (tempNode != null) {resultString += tempNode.data + ", ";tempNode = tempNode.next;} // Of whilereturn resultString;}// Of toString

这段代码在day13链表中有详细的分析,这里就不再重复赘述了。 

3.入队

我们知道链表在插入时,一共需要三步,分别是:第一步创建新的结点,第二步找到指定插入位置的前一个结点,第三步修改该指定插入位置前后的指针指向。但是,链队列不一样,因为队列只能在队尾插入,所以我们只需要在原尾指针之后增加一个新的结点即可,具体模拟如下:

    /************************ Enqueue.* * @param paraValue The value of the new node.**********************/public void enqueue(int paraValue) {Node tempNode = new Node(paraValue);tail.next = tempNode;tail = tempNode;}// Of enqueue

首先,定义一个新的结点tempNode;然后通过语句tail.next = tempNode;将原尾指针与新结点链接起来(相当于在原尾指针后面插入新结点);最后不要忘了更新尾指针,将新结点令为新的尾指针(因为尾指针始终指向队尾)。

4.出队

由于链表的存储方式是在物理空间中直接、任意创建一个新的结点,所以它并没有明确的上限,所以在上面链队列入队时,我们并没有考虑队列是否已满的问题。但是,在出队时就需要考虑队列是否为空。

在前面,我们已经定义了头指针和尾指针,当队列为空时,显然头指针等于尾指针,所以我们就把header == tail作为判断队列是否为空的条件,并且规定队列为空时返回 -1。

    /************************ Dequeue.* * @return The value at the header.**********************/public int dequeue() {if (header == tail) {System.out.println("No element in the queue");return -1;} // Of ifint resultValue = header.next.data;header.next = header.next.next;// The queue becomes empty.if (header.next == null) {tail = header;} // Of ifreturn resultValue;}// Of dequeue

确定该队列不空后,就可以进行出队操作了。早在day13链表中,我们就已经知道头结点header的data域是无效的,没办法执行删除操作,同理这里的头指针header也是如此,所以出队时我们需要跳过头指针,从头指针后面第一个结点开始。显然,header.next就是指的头指针后面第一个结点,而header.next.data就是指头指针后面第一个结点的data域,也就是第一个有效数据(即需要删除的第一个数据),所以我们将其赋给resultValue;然后再通过header.next = header.next.next;实现删除操作。

这里有一个地方需要特别注意,当队列中只有一个有效结点时,头指针header和尾指针tail的指向如图所示:

这个时候再执行header.next = header.next.next;毫无疑问就会将该有效结点和尾指针一同删掉,所以我们需要重新定义尾指针。具体方法就是,当header.next = null即队列为空时,重新定义尾指针tail = header,最后不要忘记返回所删掉的数据。

5.数据测试

接下来进行数据测试:

  • 创建LinkedQueue类的一个对象tempQueue,并调用toString()方法进行遍历(此时肯定为空)
  • 进行入队操作,利用for循环向空队列中插入5个队列元素,并输出
  • 出队一次,并输出
  • 再循环执行出队操作5次,并输出
  • 最后再循环入队3次,输出
    /************************ The entrance of the program.* * @param args Not used now.**********************/public static void main(String args[]) {LinkedQueue tempQueue = new LinkedQueue();System.out.println("Initialized, the list is: " + tempQueue.toString());for (int i = 0; i < 5; i++) {tempQueue.enqueue(i + 1);} // Of for iSystem.out.println("Enqueue, the queue is: " + tempQueue.toString());tempQueue.dequeue();System.out.println("Dequeue, the queue is: " + tempQueue.toString());int tempValue;for (int i = 0; i < 5; i++) {tempValue = tempQueue.dequeue();System.out.println("Looped delete " + tempValue + ", the new queue is: " + tempQueue.toString());} // Of for ifor (int i = 0; i < 3; i++) {tempQueue.enqueue(i + 10);} // Of for iSystem.out.println("Enqueue, the queue is: " + tempQueue.toString());}// Of main

6.完整的程序代码

package datastructure;/*** Linked queue.* * @author Xin Lin 3101540094@qq.com.*/
public class LinkedQueue {/*** An inner class.*/class Node {/*** The data.*/int data;/*** The reference to the next node.*/Node next;/********************* * The constructor.* * @param paraValue The data.******************* */public Node(int paraValue) {data = paraValue;next = null;}// Of the constructor}// Of class Node/*** The header of the queue.*/Node header;/*** The tail of the queue.*/Node tail;/************************ Construct an empty sequential list.**********************/public LinkedQueue() {header = new Node(-1);// header.next = null;tail = header;}// Of the first constructor/************************ Enqueue.* * @param paraValue The value of the new node.**********************/public void enqueue(int paraValue) {Node tempNode = new Node(paraValue);tail.next = tempNode;tail = tempNode;}// Of enqueue/************************ Dequeue.* * @return The value at the header.**********************/public int dequeue() {if (header == tail) {System.out.println("No element in the queue");return -1;} // Of ifint resultValue = header.next.data;header.next = header.next.next;// The queue becomes empty.if (header.next == null) {tail = header;} // Of ifreturn resultValue;}// Of dequeue/************************ Overrides the method claimed in Object, the superclass of any class.**********************/public String toString() {String resultString = "";if (header.next == null) {return "empty";} // Of ifNode tempNode = header.next;while (tempNode != null) {resultString += tempNode.data + ", ";tempNode = tempNode.next;} // Of whilereturn resultString;}// Of toString/************************ The entrance of the program.* * @param args Not used now.**********************/public static void main(String args[]) {LinkedQueue tempQueue = new LinkedQueue();System.out.println("Initialized, the list is: " + tempQueue.toString());for (int i = 0; i < 5; i++) {tempQueue.enqueue(i + 1);} // Of for iSystem.out.println("Enqueue, the queue is: " + tempQueue.toString());tempQueue.dequeue();System.out.println("Dequeue, the queue is: " + tempQueue.toString());int tempValue;for (int i = 0; i < 5; i++) {tempValue = tempQueue.dequeue();System.out.println("Looped delete " + tempValue + ", the new queue is: " + tempQueue.toString());} // Of for ifor (int i = 0; i < 3; i++) {tempQueue.enqueue(i + 10);} // Of for iSystem.out.println("Enqueue, the queue is: " + tempQueue.toString());}// Of main
}// Of class LinkedQueue

运行结果

总结

队列是一个非常基本非常重要的数据结构,因其先进先出的特性,使得它在管理和调度顺序性任务时非常有效,在很多实际问题中,合理利用队列可以提升效率、保证数据处理的顺序性和稳定性;同时,队列还可以用来实现很多算法,比如广度优先搜索算法、消息传递等等。

队列和我们之前学过的栈都是常用的两种数据结构,也均为受限线性表,只不过前者为先进先出,适用于按顺序处理的场景,后者为先进后出,适合需要逆序处理的场景。

相关文章:

日撸Java三百行(day17:链队列)

目录 一、队列基础知识 1.队列的概念 2.队列的实现 二、代码实现 1.链队列创建 2.链队列遍历 3.入队 4.出队 5.数据测试 6.完整的程序代码 总结 一、队列基础知识 1.队列的概念 今天我们继续学习另一个常见的数据结构——队列。和栈一样&#xff0c;队列也是一种操…...

Android摄像头采集选Camera1还是Camera2?

Camera1还是Camera2&#xff1f; 好多开发者纠结&#xff0c;Android平台采集摄像头&#xff0c;到底是用Camera1还是Camera2&#xff1f;实际上&#xff0c;Camera1和Camera2分别对应相机API1和相机API2。Android 5.0开始&#xff0c;已经弃用了Camera API1&#xff0c;新平台…...

零基础5分钟上手亚马逊云科技AWS核心云开发/云架构 - 创建高可用数据库集群

简介&#xff1a; 欢迎来到小李哥全新亚马逊云科技AWS云计算知识学习系列&#xff0c;适用于任何无云计算或者亚马逊云科技技术背景的开发者&#xff0c;让大家零基础5分钟通过这篇文章就能完全学会亚马逊云科技一个经典的服务开发架构方案。 我将每天介绍一个基于亚马逊云科…...

力扣315.计算右侧小于当前元素的个数

力扣315.计算右侧小于当前元素的个数 离散化 树状数组 const int N 100010;int tr[N],n;class Solution {public:vector<int> countSmaller(vector<int>& nums) {n nums.size();vector<int> tmp(nums);vector<int> res(n);memset(tr,0,sizeo…...

websocket,css动画和css-position、display、区别

一、websocket codereturn {// 用于存储 WebSocket 返回的状态数据statusList: [],},mounted() {this.setupWebSocket();this.startBlinking();},methods: {setupWebSocket() {// 创建 WebSocket 连接const socket = new WebSocket(ws://xxx.xxx:xxx/xxx);// WebSocket 连接成功…...

前端获取视频文件宽高信息和视频时长

安装 yarn add video-metadata-thumbnails | npm install video-metadata-thumbnails引入依赖包 import { getMetadata } from video-metadata-thumbnails使用 if (file.name.includes(mp4)) {if (file) {try {console.log(file)// 获取视频的元数据const metadata await …...

【区块链+医疗健康】基于区块链的药品类监管应用管理系统 | FISCO BCOS应用案例

退热类药品的购药信息及政企互动信息等各项数据的安全性、保密性、真实性&#xff0c;不仅影响着监管部门的科学监管、 有效监管&#xff0c;也影响着企业的经营安全、诚信口碑&#xff0c;是区域药品安全监管工作进展的直观体现。 江苏数予科技有限公司构建基于区块链的药品类…...

MySQL4多表查询 内连接

多表查询 数据准备 CREATE DATABASE db4; USE db4; -- 创建部门表 create table if not exists dept(deptno varchar(20) primary key , -- 部门号name varchar(20) -- 部门名字 );-- 创建员工表 create table if not exists emp(eid varchar(20) primary key , -- 员工编号…...

Java -数组

1.一维数组 1.1数组定义 public class Main {public static void main(String[] args) throws Exception {int[] a new int[10];float[] f new float[10];double[] d new double[10];char[] c new char[10];} } 1.2 初始化 public class Main {public static void main(S…...

.prettierrc.js 有什么用

.prettierrc.js 是 Prettier 代码格式化工具的配置文件。 1. 作用 Prettier 是一个用于统一代码风格的工具&#xff0c;它可以使代码更具可读性和一致性。.prettierrc.js 文件用于自定义 Prettier 的格式化规则。 通过配置 .prettierrc.js&#xff0c;团队中的开发者可以遵循…...

haproxy七层代理

一.haproxy的基本部署 1.RS上装nginx [rootwebserver1 ~]# dnf install nginx -y 2.再RS上写入测试信息 [rootwebserver1 ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index.html [rootwebserver1 ~]# systemctl enable --now nginx [rootwebserver…...

<数据集>柑橘缺陷识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1290张 标注数量(xml文件个数)&#xff1a;1290 标注数量(txt文件个数)&#xff1a;1290 标注类别数&#xff1a;4 标注类别名称&#xff1a;[Orange-Green-Black-Spot, Orange-Black-Spot, Orange-Canker, Orange…...

Go开发后端和Vue3开发前端的前后端分离框架中自己手戳一个OA流程审批、工作流引擎给新时代一个漂亮便捷的工作流引擎

前言 在软件项目开发中&#xff0c;我们都会接触到流程审批的需要业务&#xff0c;我们以往用的最多就是如下图这种流程编辑引擎插件&#xff1a; 以上截图中的流程工具是不是大家常见的呀&#xff01;感觉很丑拿不出手呀&#xff01;在当前行业内卷及竞争激烈情况下&#xff…...

深入理解 toDto 与 toEntity:结合 Eladmin 框架的最佳实践

在现代软件开发中&#xff0c;尤其是后端开发中&#xff0c;数据传输对象&#xff08;DTO&#xff09;和实体对象的转换是一个常见且重要的操作。理解和正确实现这种转换不仅能提高代码的可维护性&#xff0c;还能提升应用的性能和安全性。本文将深入探讨 toDto 和 toEntity 方…...

基于区块链的供应链应用开发

区块链的供应链溯源应用开发 一 、环境准备 (1)更新镜像源 apt update(2)安装(openssl、jdk、git) apt -y install openssl default-jdk git(3)配置JAVA_HOME环境变量 echo “export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/” >> /etc/profilesource /etc…...

获取GORM执行时的sql字符串

示例&#xff1a; import "log" func GetDetail(tx *gorm.DB,id int)(data any,err error){var query tx.Session(&gorm.Session{DryRun: true})err query.Where("id ?", id).First(&res).Errorif err!nil{zap.L().Error("get detail er…...

Linux系统使用Docker安装RStudio服务并实现任意浏览器远程访问

文章目录 前言1. 安装RStudio Server2. 本地访问3. Linux 安装cpolar4. 配置RStudio server公网访问地址5. 公网远程访问RStudio6. 固定RStudio公网地址 前言 RStudio Server 使你能够在 Linux 服务器上运行你所熟悉和喜爱的 RStudio IDE&#xff0c;并通过 Web 浏览器进行访问…...

【原创】springboot+mysql法律咨询网设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…...

Vue 应用实例的关键方法与配置案例二

目录 createApp createSSRApp app.mount app.unmount app.component app.directive Vue3.X自定义全局指令 Vue2.X自定义全局指令 app.use app.mixin 非 VIP 用户能够免费下载博文资源 createApp 详见上一章节:Vue 应用实例的关键方法与配置案例一-CSDN博客 createSS…...

Java面试题--JVM大厂篇之破解 JVM 性能瓶颈:实战优化策略大全

目录 引言: 正文: 1. 常见的JVM性能问题 频繁的GC导致应用暂停 内存泄漏导致的内存不足 线程争用导致的CPU利用率过高 类加载问题导致的启动时间过长 2. 优化策略大全 2.1 代码层面的优化 2.1.1 避免不必要的对象创建 2.1.2 优化数据结构的选择 2.1.3 使用并发工具…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

Python爬虫(四):PyQuery 框架

PyQuery 框架详解与对比 BeautifulSoup 第一部分&#xff1a;PyQuery 框架介绍 1. PyQuery 是什么&#xff1f; PyQuery 是一个 Python 的 HTML/XML 解析库&#xff0c;它采用了 jQuery 的语法风格&#xff0c;让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...

[10-1]I2C通信协议 江协科技学习笔记(17个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17...

LeetCode 2894.分类求和并作差

目录 题目&#xff1a; 题目描述&#xff1a; 题目链接&#xff1a; 思路&#xff1a; 思路一详解&#xff08;遍历 判断&#xff09;&#xff1a; 思路二详解&#xff08;数学规律/公式&#xff09;&#xff1a; 代码&#xff1a; Java思路一&#xff08;遍历 判断&a…...

调试快捷键 pycharm vscode

目录 调试快捷键 pycharm vscode 修改快捷键 方法 1&#xff1a;通过菜单打开 方法 2&#xff1a;用快捷键打开 调试快捷键 pycharm Resume Program F9 Step Over F8 两个离的比较近&#xff0c;比较方便&#xff0c;比vscode的好。 vscode Continue F5 改为F9 S…...