数据结构—循环队列(环形队列)

循环队列(环形队列)

  • 循环队列的概念及结构
  • 循环队列的实现

循环队列的概念及结构

循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

循环队列的一个好处是可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

在这里插入图片描述
注:循环队列的空间大小是固定的

循环队列的实现

环形队列可以使用数组实现(超出数组的范围回到起始位置),也可以使用循环链表实现(尾指针的next指向头节点)。选用数组实现循环队列更好,因为数组缓存利用率更高,没有扩容的代价。

环形队列实际开辟的空间大小要比所存数据的队列长度多开辟一个空间的大小。如果环形队列实际开辟的空间大小和所存储数据个数一样时,会导致环形队列所处空的状态和满的状态是一样的。这样便无法区分。

在这里插入图片描述

因此环形队列必须多留出一个空间,这个空间不能存放数据,这样才能很好的区别环形队列的状态是空还是满。

在这里插入图片描述

在这里插入图片描述
在环形队列中,队列为空时,队头队尾指向同一个位置。当队列不为空时,队头指向插入的第一个数据,队尾指向最后一个数据的下一个位置。当tail+1等于front时,说明环形队列已满。

循环队列的定义

循环队列选择用数组实现,循环队列需要用一个指针来指向存储队列数据的空间,用两个变量来记录队列中存储数据的起始(对头)和末尾(队尾)的数组位置,最后用一个变量记录队列的存储数据的最大容量。

typedef struct {int *a;int front;int tail;int k;
} MyCircularQueue;

循环队列的初始化

循环队列的初始化首先创建一个循环队列,其次对该结构体的成员进行初始化即可。

MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* cur=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));cur->a=(int *)malloc(sizeof(int)*(k+1));cur->k=k;cur->front=0;cur->tail=0;return cur;
}

注:k表示的是设置队列的长度

循环队列的入队列

入队列操作首先要判断循环队列是否已满,如果满了则返回假;如果没满则向循环队列插入一个数据(即在tail位置放数据)然后tail向后挪动一个位置,最后返回真。

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {assert(obj);if(myCircularQueueIsFull(obj)){return false;}obj->a[obj->tail]=value;obj->tail++;obj->tail=obj->tail%(obj->k+1);return true;
}

注:tail的位置为k+1时,就需要对tail进行处理防止tail对数组进行越界访问。这也遵循了循环队列的原则,当访问到数组末尾时再次访问应该访问到数组的起始位置。

循环队列的出队列

出队列操作首先判断循环队列是否为空,如果为空了,则出队列失败返回假;如果不为空则从循环队列中删除一个元素(即只需将front往后挪一个位置即可),如果成功删除则返回真。

bool myCircularQueueDeQueue(MyCircularQueue* obj) {assert(obj);if(myCircularQueueIsEmpty(obj)){return false;}obj->front++;obj->front%=obj->k+1;return true;
}

注:当front为k+1时处理方式和入队列的tail类似。

获取循环队列的对头数据

获取循环队列的对头数据首先判断循环队列是否为空,如果为空则返回-1;如果不为空只需通过front的位置获取数组中的数据并返回该数据即可。

int myCircularQueueFront(MyCircularQueue* obj) {assert(obj);if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[obj->front];
}

获取循环队列的对尾数据

获取循环队列的对尾数据首先判断循环队列是否为空,如果为空则返回-1;如果不为空只需通过tail获取tail的前一个位置的数组中的数据并返回该数据即可。

int myCircularQueueRear(MyCircularQueue* obj) {assert(obj);if(myCircularQueueIsEmpty(obj)){return -1;}int prevtail=obj->tail-1;if(obj->tail==0){prevtail=obj->k;}return obj->a[prevtail];
}

注:当tail为0时,此时取队尾数据时取的是数组下标为k的元素数据。因为tail表示的是最后一个有效数据的下一个位置。

循环队列的判空

循环队列的判空只需判断队头和队尾是否相等即可

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {assert(obj);return obj->front==obj->tail;
}

循环队列的判满

循环队列的判满只需判断队尾的下一个位置和队头是否相等即可

bool myCircularQueueIsFull(MyCircularQueue* obj) {assert(obj);return obj->front==((obj->tail)+1)%(obj->k+1);
}

注:当tail为k时tail的下一个位置为0,此时处理情况和出入队列的处理情况类似。

循环链表的销毁

循环链表的销毁首先要对循环链表结构体中的成员进行释放,然后再对循环链表进行释放即可。

void myCircularQueueFree(MyCircularQueue* obj) {assert(obj);free(obj->a);free(obj);obj=NULL;
}

注意:

  • 环形队列中存储数据的空间是一开始就要创建好的,删除数据时是front指针往后走,存储数据的空间不销毁。插入数据时是往tail所指向的空间放数据,不申请空间,tail往后走。
  • 循环队列如果用链表实现最好用双向链表实现,单向链表不好去找循环队列的队尾数据,而且采用链表的形式实现需要定义节点的结构体以及在初始化方面需要创建k+1个节点并建立连接,这样操作起来很麻烦没有数组省事,因此用数组实现循环队列更好。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

同为科技(TOWE)带热插拔功能机柜PDU插座的应用

所谓热插拔(hot-plugging或Hot Swap),即带电插拔,指的是在不关闭系统电源的情况下,将模块、板卡插入或拔出系统而不影响系统的正常工作,从而提高了系统的可靠性、快速维修性、冗余性和对灾难的及时恢复能力…

HVV爆火漏洞:最新 WPS RCE (远程命令执行) 复现

最近HVV爆出的很火的WPS命令执行漏洞&#xff0c;其实并不是0DAY&#xff0c;早在2019年就出现了&#xff0c;只不过最近EXP才公开。接下来我们来复现一遍。 0x00 影响版本 WPS Office 2023 个人版 < 11.1.0.15120WPS Office 2019 企业版 < 11.8.2.12085 0x01 环境配置…

[管理与领导-50]:IT基层管理者 - 8项核心技能 - 5 - 沟通是润滑剂

目录 前言&#xff1a; 一、什么是沟通 1.1 定义 1.2 沟通模型 1.3 沟通的六层次模型 1.4 为什么需要沟通 二、沟通的五维度 三、沟通的原则 3.1 以终为始 3.2 双赢思维&#xff1a;人们只会做对自己有利的事 3.3 牵善的思维 四、沟通的过程 五、沟通技巧 六、深…

【HSPCIE仿真】输入网表文件(1)基本内容和基本规则

输入网表文件 1. 输入网表文件基本内容2. 输入网表文件示例3. 一些基本规则4. 数值表示5. 压缩文件格式的读取6. 参数和表达式 从HSPICE的仿真流程看&#xff0c;出去初始化配置过程&#xff0c;真正的仿真是从输入网表文件开始的。 HSPICE 根据输入网表文件&#xff08; inpu…

【80天学习完《深入理解计算机系统》】第十一天 3.4 跳转指令

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

深度学习7:生成对抗网络 – Generative Adversarial Networks | GAN

生成对抗网络 – GAN 是最近2年很热门的一种无监督算法&#xff0c;他能生成出非常逼真的照片&#xff0c;图像甚至视频。我们手机里的照片处理软件中就会使用到它。 目录 生成对抗网络 GAN 的基本原理 大白话版本 非大白话版本 第一阶段&#xff1a;固定「判别器D」&#x…

设计模式-适配器模式

核心思想 见名知意&#xff0c;是作为两个不兼容的接口的桥梁&#xff0c;属于结构型模式使得原来由于接口不兼容而不能一起工作的那些类可以一起工作 常见的几类适配器 类的适配器模式 想将一个类转换成满足另外一个新接口的类时&#xff0c;可以使用类的适配器模式&#x…

基于CH552G主控的开源九键小键盘(资料齐全)

Content 1. 前言2. CH55X Arduino平台环境搭建2.1 常规安装2.2 HFS挂载本地服务器安装 3. 例程使用3.1 工程下载及编译3.2 程序烧录 1. 前言 芯片选型&#xff1a;CH552G 本文主要解决Arduino下CH552G芯片包的环境配置问题 开源地址&#xff1a;CV键盘有线小键盘 - 嘉立创ED…

一分钟学会用pygame制作棋盘背景

一分钟一个Pygame案例&#xff0c;这一集我们来学习一下如何生成一个视频中的棋盘背景效果&#xff0c;非常非常简单。 视频教程链接&#xff1a;https://www.bilibili.com/video/BV17G411d7Ah/ 当然我们这里是用来做页面的背景&#xff0c;你也可以拿来做别的效果&#xff0…

fdm-cli,一个致力于管理项目初始化模板的工具脚手架

希望各位可以了解fdm-cli&#xff0c;并在合适的时候尝试使用一下。 阅读本文你将获得 一个&#xff08;好用的&#xff09;项目模板初始化工具这个&#xff08;好用的&#xff09;工具的使用方法给作者点一个 star 的机会 一、不愿再复制粘贴 小N每次在写项目的时候&#x…

JVM及垃圾回收机制

文章目录 1、JVM组成&#xff1f;各部分作用&#xff1f;1.1 类加载器&#xff08;Class Loaders&#xff09;1.2 运行时数据区&#xff08;Runtime Data Area&#xff09;1.3 执行引擎&#xff08;Execution Engine&#xff09;1.4 本地方法接口&#xff08;Native Interface&…

按钮权限控制

搜索关键字&#xff1a; 自定义指令传参| "自定义指令""dataset"|自定义指令dataset| "Vue""directives"|vue按钮权限实现 1、完整代码&#xff1a; <template> <div> <el-breadcrumb separator-class"el-icon…

淘宝免费爬虫数据 商品详情数据 商品销售额销量API

场景&#xff1a;一个宽敞明亮的办公室&#xff0c;一位公司高管坐在办公桌前。 高管&#xff08;自言自语&#xff09;&#xff1a;淘宝&#xff0c;这个平台上商品真是琳琅满目&#xff0c;应该有不少销售数据吧。我该怎么利用这些数据呢&#xff1f; 突然&#xff0c;房间…

Oracle跨库访问DBLINK

1. DBLINK的介绍 Oracle在进行跨库访问时&#xff0c;可以创建DBLINK实现&#xff0c;比如要将UAT的表数据灌入开发环境&#xff0c;则可以使用UAT库为数据源&#xff0c;通过DBLINK实现将查出的数据灌入开发库。 简而言之就是在当前数据库中访问另一个数据库中的表中的数据 2…

js中作用域的理解?

1.作用域 作用域&#xff0c;即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变量和其他资源的可见性 举个例子 function myFunction() {let inVariable "函数内部变量"; } myFunction();//要先执行这…

网络安全在医疗行业中的重要性

不可否认&#xff0c;现代世界见证了技术和医疗行业的交织&#xff0c;塑造了我们诊断、治疗和管理健康状况的新方式。随着电子健康记录取代纸质文件&#xff0c;远程医疗缩短了患者和医疗服务提供者之间的距离&#xff0c;数字化转型既是福音&#xff0c;也是挑战。最近的全球…

Hightopo 使用心得(6)- 3D场景环境配置(天空球,雾化,辉光,景深)

在前一篇文章《Hightopo 使用心得&#xff08;5&#xff09;- 动画的实现》中&#xff0c;我们将一个直升机模型放到了3D场景中。同时&#xff0c;还利用动画实现了让该直升机围绕山体巡逻。在这篇文章中&#xff0c;我们将对上一篇的场景进行一些环境上的丰富与美化。让场景更…

【算法专题突破】双指针 - 复写零(2)

目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 1. 题目解析 题目链接&#xff1a;1089. 复写零 - 力扣&#xff08;Leetcode&#xff09; 我先来读题&#xff0c; 题目的意思非常的简单&#xff0c;其实就是&#xff0c; 遇到 0 就复制一个写进数组&a…

主从、哨兵、集群模式有什么区别 ?

目录 1.Redis 多机部署的方式 2.主从、哨兵、集群模式有什么区别 2.1 主从同步 2.2 哨兵模式 2.3 集群模式 1.Redis 多机部署的方式 Redis 多机部署主要有 3 种方式&#xff1a; 1. 主从同步&#xff1a;主要存储数据的节点叫做主节点&#xff08;master&#xff09;&…

探秘工业设计的魅力:引领时尚潮流,打造个性空间

工业风格源自于上世纪初的工人阶级世界&#xff0c;几十年来一直充满诱惑力。它们由金属集合物&#xff0c;焊接、铆钉这些暴露在外的结构组建&#xff0c;融进了更多装饰性的曲线&#xff0c;再与素雅的色彩搭配形成&#xff1a;让我们来看看这种历史悠久的&#xff0c;在室内…