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

数据结构:图文详解 队列 | 循环队列 的各种操作(出队,入队,获取队列元素,判断队列状态)


目录

队列的概念

队列的数据结构

队列的实现

入队

出队

获取队头元素

获取队列长度

循环队列的概念

循环队列的数据结构

循环队列的实现

判断队列是否为空

判断队列是否已满

入队

出队

得到队头元素

得到队尾元素


队列的概念

队列(Queue)是一种数据结构,是一种先进先出(First-In-First-Out,FIFO)的线性数据结构。它只允许在列表的一端进行插入操作(入队),在另一端进行删除操作(出队),即队头进行删除操作,队尾进行插入操作。队列常用的操作有入队(Enqueue)、出队(Dequeue)、获取队头元素(Front/Peek)、获取队列长度(Size/Length)等。

图示如下:

队列的特点是按照元素加入的先后顺序进行操作,先加入队列的元素会先被取出,后加入的元素会后被取出。这种特性常常被用于模拟实际生活中的排队场景,例如银行柜台排队、CPU任务调度等。


队列的数据结构

队列可以用数组或链表来实现。数组实现的队列需要预先分配一定的空间,但是在操作中效率较高;链表实现的队列没有固定的空间限制,但是在操作中可能需要更多的时间和空间。

这里笔者以链表进行演示:

public class MyQueue {static class ListNode {int val;//存放数据ListNode pre;//前驱指针ListNode next;//后驱指针public ListNode(int val) {this.val = val;}}private ListNode head;//记录头节点private ListNode last;//记录尾部节点
}

队列的实现

入队

因为我们使用的是链表来模拟实现,所以对于入队的操作就相当于使用尾插法(头插法),入队图示:

当队列为空的时候需要进行特殊处理,不然会造成空指针异常,队列为空的时候让我们的头指针和尾指针都指向这个节点就可以,如果队列不为空就正常的使用尾插法,尾插法图示:

    //入队public void enqueue(int val) {ListNode newNode = new ListNode(val);if (head == null) {head = newNode;last = newNode;}else {newNode.pre = last;last.next = newNode;last = newNode;}}

出队

队列是个单向的数据结构,对于入队我们使用了尾插法,那么出队就需要使用删除头节点的方法,出队的图示如下:

出队实际上是对于队头节点的删除,所以当队内没有节点的时候我们就不能进行这样的操作,我们直接抛出一个异常,在可以抛出的情况下,我们定义一个 val变量 来存放我们要删除的值,以便返回。当队列只有一个元素的时候要进行特殊处理,不然后面的程序会报空指针异常,这种情况下,我们需要先拿到头节点的值,然后将头节点置空,最后返回这个值;其余情况我们就正常进行删除操作,先拿到头节点的值然后让头节点后移,再让改变现在头节点的前驱指针,让我们要删除的数据无法被访问,最后返回这个值

    //出队public int dequeue() {if (head == null) {throw new ExceptionOfEmpty("队列为空,无法操作");}int val = -1;//当队列只有一个元素的时候要进行特殊处理,不然后面的程序会报空指针异常if (head.next == null) {val = head.val;head = null;last = null;return val;}//对于其他正常位置元素的处理val = head.val;head = head.next;head.pre = null;return val;}

获取队头元素

获取队头元素则十分的简单,使用个临时变量拿到头节点的值然后返回就可以了

    //拿出队列的首个元素进行查看public int peek() {if (head == null) {throw new ExceptionOfEmpty("队列为空,无法操作");}int val = head.val;return val;}

获取队列长度

获取队列的长度也非常的简单,使用一个新的节点挨个变量,然后累加计数器最后返回就可以

    //获取队列长度public int size() {int count = 0;ListNode cur = head;while (cur != null) {cur = cur.next;count++;}return count;}

循环队列的概念

循环队列是一种特殊的队列数据结构,它允许队列的头尾相接,形成一个环。循环队列解决了普通队列的一些缺点,如空间浪费和在元素出队后无法再次入队的问题。

循环队列通常使用数组来实现,其内部有两个指针frontrear,分别指向队列的第一个元素和最后一个元素的下一个位置。初始化时,frontrear都指向数组的第一个位置。

当往循环队列中插入元素时,将元素放入rear指向的位置,并将rear指针向后移动一位。如果rear指针到达数组的尾部,则将其指向数组的起始位置。当从循环队列中删除元素时,将front指针向后移动一位,表示该元素已出队列。如果front指针到达数组的尾部,则将其指向数组的起始位置。

图示如下:

使用循环队列可以实现高效的元素入队和出队操作,因为循环队列的空间利用率较高。当队列满时,rear指针和front指针会指向同一个位置,此时队列被认为是满的。而在普通队列中,即使队列中还有空闲位置,当rear指针到达数组的尾部时,无法再向队列中插入元素。

循环队列通过循环利用数组空间,解决了普通队列的空间浪费和无法再次入队的问题,提高了队列的空间利用率和性能。


循环队列的数据结构

对于循环队列,我们可以使用数组来模拟实现,分别有俩个指针指向整个数组的首部和尾部

public class MyCircularQueue {public int[] elem;//存放数据public int front;//指向队头public int rear;//指向队尾MyCircularQueue(int k) {elem = new int[k];}
}

循环队列的实现

对于循环队列的实现,其实难点就在于判断队列的状态,分得清队列已满和队列为空的情况就可以,其余的操作实际上都是非常简单的数组的添加和删除元素

另外很重要的一点就是,循环队列需要体现出循环的概念,所以不管是队头指针还是队尾指针,我们在操作的时候都需要除以这个数组的模

判断队列是否为空

队列为空是怎么样的状态?为空,也就是说队列内什么都没有,队列的开始就是队列的结束,也就是队头指针和队尾指针指向同一个地方,如图所示:

    //判空 front和rear相遇public boolean isEmpty() {return front == rear;}

判断队列是否已满

队列已满是怎么样的状态?队列已满就是说队列每一个位置都有元素存放,这个情况下,如果队尾指针再往后走一步,就相当于回到了第二轮的起点,如图所示:

那么也就是说,当队尾指针再往后走一步的值除以整个队列的大小,就等于头指针的大小 

    //判空 front和rear相遇public boolean isFull() {return (rear + 1) % elem.length == front;}

入队

入队的时候,我们先要判断队列是否已满,满了就返回false表示入队失败;没有满的话就进行入队,也就是从数组的最后位置放个元素,然后再更改队尾指针指向,图示如下:

出队

出队的实现实际上就是对数组的第一个元素进行删除操作,如图所示:

    //出队public boolean deQueue() {if (isEmpty()) {return false;}front = (front + 1) % elem.length;return true;}

得到队头元素

这样的操作其实就是出队操作的简化,拿到值返回即可,这里就不再赘述

    //得到队头元素public int Front() {if (isEmpty()) {return -1;}return elem[front];}

得到队尾元素

这里有一点需要注意,当我们的队列只有一个元素的时候,是需要进行特殊处理的,不然就会出现数组越界的异常,毕竟数组不存在下标为-1的元素

    //得到队尾元素public int Rear() {if (isEmpty()) {return -1;}int index = (rear == 0) ? elem.length - 1 : rear - 1;return index;}



  本次的分享就到此为止了,希望我的分享能给您带来帮助,也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见

相关文章:

数据结构:图文详解 队列 | 循环队列 的各种操作(出队,入队,获取队列元素,判断队列状态)

目录 队列的概念 队列的数据结构 队列的实现 入队 出队 获取队头元素 获取队列长度 循环队列的概念 循环队列的数据结构 循环队列的实现 判断队列是否为空 判断队列是否已满 入队 出队 得到队头元素 得到队尾元素 队列的概念 队列(Queue&#xff0…...

Debezium发布历史130

原文地址: https://debezium.io/blog/2022/10/10/debezium-2.0-cr1-released/ 欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯. Debezium 2.0.0.CR1 Released October 10, 2022 by Chris Cranford rel…...

【笔记】Harmony学习:下载安装 DevEco Studio 开发工具IDE

IDE 安装 从官网下载DevEco Studio 安装包后进行安装, 安装完毕后,本地环境可能要配置相关工具,可以通过下面的诊断检测一下本地环境,通过蓝色“Set it up now” 可以快速安装。 1. Node.js (for ohpm) 2. ohpm 下载op的包管理&a…...

Electron实战之入门

一、Electron简介 1.1 Electron是什么 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的技术框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许开发者使用 JavaScript 代码来创建允许在Windows、macOS和Linux等平台。 1.2 发展历程 2013 年的时候…...

飞机大作战(c语言)

前言: 飞机大作战游戏是一种非常受欢迎的射击类游戏,玩家需要控制一架战斗机在屏幕上移动,击落敌机以获得分数。本游戏使用C语言编写,旨在帮助初学者了解游戏开发的基本概念和技巧。 在开始编写代码之前,我们需要先了…...

服务器操作系统windows和linux区别对比

阿里云服务器镜像Windows和Linux操作系统有什么区别?性能有差异吗?有,同配置下Linux性能要优于Windows,但这与阿里云无关,仅仅是linux和windows之间的区别。另外,阿里云提供的windows和linux操作系统均为正…...

吉他学习:识谱,认识节奏,视唱节奏,节拍器的使用

第九课 识谱https://m.lizhiweike.com/lecture2/29362692 第十课 基础乐理(二)——节奏篇https://mp.csdn.net/mp_blog/creation/editor?spm=1011.2124.3001.6192...

[前端开发] JavaScript基础知识 [下]

上篇:JavaScript基础知识 [上] JavaScript基础知识 [下] 字符串数组函数对象 字符串 字符串语法规则:单引号、双引号和反引号的使用 利用双引号"或者单引号所括起来双引号中不能嵌套双引号,单引号中不能嵌套单引号如果要在双引号中嵌套双引号或者…...

新版UI界面影视小程序亲测无问题带详细搭建教程

新版UI界面影视小程序亲测无问题带详细搭建教程 环境php7.0 — fileinfo–redis–sg11 mysql5.5 apache2.4 添加站点php7.0—-创建ftp—-上传后端文件《后端文件修改,/maccms/wxapi/config/dbs.php–修改当前数据库》—-设置ssl—-打开数据库安装cms 安装好后管…...

2024.2.7日总结(小程序开发4)

页面导航 页面导航是页面之间的相互跳转&#xff1a; <a>链接location.href 小程序中实现页面导航的两种方式&#xff1a; 声明式导航 在页面上声明一个<navigator>导航组件通过点击<navigator>组件实现页面跳转 编程式导航 调用小程序的导航API&…...

每日五道java面试题之java基础篇(七)

第一题. HashMap和HashTable有什么区别&#xff1f;其底层实现是什么&#xff1f; 区别 &#xff1a; HashMap⽅法没有synchronized修饰&#xff0c;线程⾮安全&#xff0c;HashTable线程安全&#xff1b;HashMap允许key和value为null&#xff0c;⽽HashTable不允许 底层实现…...

树莓派4B(Raspberry Pi 4B)使用docker搭建单机版nacos [基于docker-compose]

树莓派4B&#xff08;Raspberry Pi 4B&#xff09;使用docker搭建单机版nacos [基于docker-compose] 镜像仓库提供的基于arm64架构的nacos镜像很少&#xff0c;我选用的是centralx/nacos-server &#xff0c;它是基于nacos 2.0.4开发的。 ⚠️ 本文基于docker-compose记述构建单…...

DAY50:完全背包、爬楼梯、322、279

70 爬楼梯 &#xff08;进阶) 爬楼梯问题在我们刚开始学习动态规划的时候作为入门的问题。当时题目考虑的是1或2种走法。如果将能走的台阶设为M&#xff0c;则能产生进阶的题目。通过求解完全背包问题得到。 题目如下&#xff1a; 题目页面 如果最多能走m个台阶&#xff0c…...

MySQL性能调优篇(3)-缓存的优化与清理

MySQL数据库缓存的优化与清理 数据库缓存在MySQL中扮演着非常重要的角色&#xff0c;它可以显著提高数据库的性能和响应速度。在本篇博客中&#xff0c;我们将介绍如何优化和清理MySQL数据库的缓存&#xff0c;以进一步提高数据库的效率。 优化缓存 1. 适当调整缓存大小 My…...

Zig、C、Rust的Pk1

Zig、C、Rust的Pk1 github.com上看到“A basic comparitive analysis of C, C, Rust, and Zig.”&#xff1a;https://github.com/CoalNova/BasicCompare/tree/main 里边的代码是9个月之前的&#xff0c;用现在的zig 0.11.0 及0.12-dev都无法通过编译(具体为&#xff1a;zig-w…...

如何用 ChatGPT 做项目管理?

ChatGPT 可以通过创建和维护跨团队项目协作计划&#xff0c;让员工更容易理解他们的角色和职责。 这个协作计划里面会包括每个团队或个人要执行的具体任务&#xff0c;每个任务最后期限和任何事情之 间的依赖关系。 该场景对应的关键词库:(24 个) 项目管理、项目协作计划、跨…...

DS:树及二叉树的相关概念

创作不易&#xff0c;兄弟们来波三连吧&#xff01;&#xff01; 一、树的概念及结构 1.1 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c…...

MATLAB | 情人节画个花瓣venn图?

之前七夕节情人节各种花&#xff0c;相册&#xff0c;爱心啥的都快画够了&#xff0c;今年画个花瓣韦恩图&#xff1f; 花瓣上的数字是仅属于该类的样本数&#xff0c;而中心的数字是属于每一类的样本数 教程部分 0 数据准备 % 给组起名t1 t2 t3...t15 setName compose(t%d,…...

[日常使用] Shell常用命令

Shell是什么&#xff1f; Shell简介 Shell是操作系统的外壳&#xff0c;是用户与操作系统内核之间的主要接口。它接收用户的命令并将其传递给内核执行&#xff0c;然后将执行结果返回给用户。Shell不仅是一个命令解释器&#xff0c;也是一种强大的编程语言。常见的Shell分为图…...

QT+OSG/osgEarth编译之八十七:osgdb_p3d+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5插件库osgdb_p3d)

文章目录 一、osgdb_p3d介绍二、文件分析三、pro文件四、编译实践一、osgdb_p3d介绍 P3DXML是Panda3D引擎中使用的一种文件格式,用于描述3D场景的层次结构和属性。它是一种基于XML(eXtensible Markup Language)的文本格式,可以被Panda3D引擎读取和解析。 P3DXML文件包含了…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...