数据结构——循环队列

news2024/9/20 20:48:39

目录

循环队列的基本知识

循环队列的实现

定义

各个接口的实现


循环队列的基本知识

循环队列的定义

循环队列(Circular Queue)是一种使用固定大小的数组实现的队列,它将数组的首尾相连,形成环形,以充分利用空间并实现高效的入队(enqueue)和出队(dequeue)操作。

基本特点

  • 固定大小:循环队列通常有一个固定的大小,这意味着它能够存储的元素数量是有限的。
  • 循环利用空间:当队尾指针到达数组的末尾时,下一个元素会循环到数组的开头位置。
  • 高效操作:循环队列可以避免在数组末尾重新分配空间,从而提高入队和出队操作的效率。

基本操作

  1. 入队(Enqueue):在队尾添加一个元素。如果添加后队尾指针到达数组末尾,则循环回数组的开始位置。
  2. 出队(Dequeue):移除队首的元素。如果移除后队首指针到达数组末尾,则循环回数组的开始位置。
  3. 查看队首元素(Peek/Front):返回队首元素的值,但不移除它。
  4. 检查是否为空(IsEmpty):如果队首和队尾指针相同,且队列未满,则队列为空。
  5. 检查是否已满(IsFull):如果队尾指针在移动一位后将与队首指针相遇,或者队列的元素数量等于数组的大小,则队列为满。

适用场景

  • 当数据元素数量相对固定时,循环队列可以高效地利用内存空间。
  • 在需要频繁入队和出队操作的场景中,循环队列可以减少内存分配和回收的开销。

循环队列的实现

定义

循环队列的实现需要一个定长数组arr,一个头指针head,一个尾指针rear,还有用于记录数据个数的变量k。

​
typedef struct 
{
    int* arr;
    int head;
    int rear;
    int k;

} MyCircularQueue;

​

各个接口的实现

创造k个数据的循环队列

​
​
​
MyCircularQueue* myCircularQueueCreate(int k) 
{
    MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));

    obj->arr = (int*)malloc(sizeof(int)*(k+1));
    obj->head = obj->rear = 0;
    obj->k = k;
    return obj;
}

​

​

这里为什么数据个数是k个,但开了k+1个空间?

首先,head指向队列的第一个元素,rear指向队列最后一个元素的下一个位置。

当rear == head的时候,队列可能是空,也可能是满;当队列满的时候,rear指向的应该是最后一个元素的下一个位置,也就是head(循环队列);当队列为空时,rear == head(rear和head可能不等于0)

所以判断队列为空和队列为满的条件是冲突的,所以特意开多一个空间,这样的话这个循环数组的任意时刻都有一个位置不存放元素,这两个判断条件也就不冲突了。

销毁循环队列

释放动态开辟的数组,把head、rear、k值0即可。

void myCircularQueueFree(MyCircularQueue* obj) 
{
    free(obj->arr);
    obj->head = obj->rear = obj->k = 0;
}

判断循环队列是否为空

判断rear和head是否相等就可以。

​
bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{
    return obj->head == obj->rear;
}

​

判断循环队列是否为满

其实在创建数组的时候多开的那个空间就是专门为了rear准备的,这里队列为满时rear就不会和head指向同一位置,而是指向多开出来的那个空间。

理想情况下,rear + 1 == head就说明队列为满。

而如果rear刚好是数组的最后下标,rear+1就会越界,所以需要模上capacity(k + 1)。

bool myCircularQueueIsFull(MyCircularQueue* obj) 
{
    return (obj->rear + 1) % (obj->k + 1) == obj->head;
}

插入元素到队尾(入队列)

如果插入成功,返回true。

注意先判断队列是否为满,如果满,返回false。

还需注意rear是否会越界的问题

​
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    obj->arr[obj->tail++] = value;
    //记得让rear模上一个周期(k+1),以防越界
    obj->rear %= (obj->k + 1);
    return true;
}

​

删除队头元素(出队列)

删除成功就返回true。

注意判断队列为空和head的越界问题即可。

bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    obj->head++;
    //防止head越界
    obj->head %= (obj->k + 1);
    return true;
}

获取队头元素

注意队列为空,为空就返回-1。

int myCircularQueueFront(MyCircularQueue* obj) 
{
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }

    return obj->arr[obj->head];
}

获取队尾元素

还是注意如果队列为空,为空就返回-1。

​
int myCircularQueueRear(MyCircularQueue* obj) 
{
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }

    return obj->arr[(obj->rear + obj->k) % (obj->k + 1)];
}

​

这里不能直接return obj->arr[rear - 1],因为rear有可能是0,还是得对rear进行特殊处理。

(rear + k + 1 - 1)% (k + 1)就可以处理上面这种特殊情况。


拜拜,下期再见😏

摸鱼ing😴✨🎞

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

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

相关文章

react组件优化之React.PureComponent,React.memo

在开发中我们经常会考虑项目的优化问题,react作为现在前端的热门框架用的人肯定是非常的多。项目的优化问题也是非常重要的一部分,能大大提高项目的流畅度,用户体验会非常好。react项目中会用到大量的组件嵌套,减少一些组件的不必…

第二证券:虚拟现实概念强势,博士眼镜三连板,星星科技涨停

虚拟现实概念14日盘中再度走强,到发稿,硕贝德、博士眼镜、星星科技“20cm”涨停,亚世光电、亿道信息、卓翼科技亦涨停,佳禾智能涨超9%。 值得注意的是,博士眼镜已连续3个交易日涨停。公司昨日在出资者互动途径表示&am…

【二叉树进阶】--- 根据二叉树创建字符串

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: 数据结构 从本篇文章开始,博主将分享一些结合二叉树的进阶算法题。 🏠 根据二叉树创建字符串 📌 题目内容 根据二叉…

若依框架中的mybatis依赖在哪里?

对于刚刚接触若依框架的朋友,可能会比较懵逼,因为他可能在依赖文件中没有找到mybatis的依赖是在什么地方引入的,所以本章教程,就告诉你这个依赖是在什么地方引入的。 在ruoyi-common模块中的pom.xml 存在一个pagehelper-spring-boot-starter <!-- pagehelper 分页插件 -…

一文HDMI (High-Definition Multimedia Interface)

HDMI&#xff08;High-Definition Multimedia Interface&#xff0c;高清多媒体接口&#xff09;是一种紧凑的音视频接口&#xff0c;它能够将未压缩的视频数据以及压缩或未压缩的数字音频数据&#xff0c;从符合HDMI标准的源设备无缝传输到兼容的计算机显示器、视频投影仪、数…

springboot学生练习自测系统-计算机毕业设计源码48462

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2 学生练习自测系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.4 系统用例分析 2.5本章小…

STM32学习笔记13-FLASH闪存

FLASH简介 STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分&#xff0c;通过闪存存储器接口&#xff08;外设&#xff09;可以对程序存储器和选项字节进行擦除和编程读写FLASH的用途&#xff1a; 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 通过在…

【瑞芯微RV1126(板端摄像头图像数据采集)】②使用v4l2视频设备驱动框架采集图像数据,按键拍照并显示

RV1126开发板&#xff1a;使用v4l2视频设备驱动框架采集图像数据 前言一、按键二、LCD显示三、V4L2 摄像头应用编程四、完整代码 前言 本系列的目的是&#xff0c;不仅仅将能够进行图片推理的模型部署于板端&#xff0c;还提供了两种摄像头数据采集的方法&#xff0c;集成到自…

【python】OpenCV—Optical Flow

文章目录 1、光流2、Opencv 中光流的实现3、稀疏光流4、密集光流4.1、farneback4.2、lucaskanade_dense4.3、rlof 5、涉及到的库5.1、cv2.goodFeaturesToTrack5.2、cv2.calcOpticalFlowPyrLK5.3、cv2.optflow.calcOpticalFlowSparseToDense5.4、cv2.calcOpticalFlowFarneback5.…

超赞!墙裂推荐这款开箱即用、永久免费的运维监控平台

文章目录 简介一、初次印象&#xff1a;直观而强大的界面二、深入体验&#xff1a;6个重点功能模块1、告警管理2、综合监控3、业务服务4、网络拓扑5、可视化管理6、知识库7、报表管理 Lerwee AI 在当今这个数字化时代&#xff0c;企业依赖于强大的IT基础设施来支持其日常运营。…

微软Detours Hook库编译与使用

Detours 是微软开发的一个强大的Windows API钩子库&#xff0c;用于监视和拦截函数调用。它广泛应用于微软产品团队和众多独立软件开发中&#xff0c;旨在无需修改原始代码的情况下实现函数拦截和修改。Detours 在调试、监控、日志记录和性能分析等方面表现出色&#xff0c;已成…

java之如何爬取本地数据(利用正则表达式)

public class RegexDemo4 {public static void main(String[] args) {String s"程序员学习java&#xff0c;""电话&#xff1a;181512516758&#xff0c;18512508907" "或者联系邮箱&#xff1a;boniuitcast.cn&#xff0c;""座机电话&…

基于vue框架的RTY个人记账管理系统03jc1(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,收入分类,支出分类,收入信息,支出信息,开支预算,负债信息 开题报告内容 基于Vue框架的RTY个人记账管理系统 开题报告 一、研究背景与意义 随着社会经济的快速发展和人们生活水平的不断提升&#xff0c;个人财务管理成为越来越…

centos7.9 内核升级至5.4

一、修改yum源 查看现有系统内核版本&#xff1a; 备份系统自带的yum源&#xff1a; 一、修改CentOS-Base.repo ## cat CentOS-Base.repo # CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the # update status of each mirror t…

详细解读keepalived高可用集群

一.高可用集群 1.1 集群类型 LB&#xff1a;Load Balance 负载均衡LVS/HAProxy/nginx&#xff08;http/upstream, stream/upstream&#xff09;HA&#xff1a;High Availability 高可用集群数据库、RedisSPoF: Single Point of Failure&#xff0c;解决单点故障HPC&#xff1…

docker容器挂载USB串口设备

1、在容器所在宿主机确认USB串口设备 有两种方法可以将USB设备挂载到容器中: 使用--privileged参数或者使用--device参数 --prvleged参数可以让容器拥有主机的所有特权&#xff0c;包括所有可以访问USB设备。--device参数可以针对特定的设备挂载到容器中。 [rootdocker40 ~]…

【经验总结】ShardingSphere+Springboot-01模式参数配置

文章目录 详细配置&#xff08;boot&#xff09;一、模式配置&数据源配置1.1 模式配置1.2 数据源配置1.3 默认数据源的配置默认数据源配置结论 二、基础属性配置2.1 在日志中打印 SQL2.2 在程序启动和更新时&#xff0c;是否检查分片元数据的结构一致性 详细配置&#xff0…

JavaScript高阶笔记总结第三天:(JavaScript高阶完结)

Xmind鸟瞰图&#xff1a; 简单文字总结&#xff1a; js高阶笔记总结&#xff1a; 严格模式&#xff1a; 1.开启严格模式&#xff1a;"use strict" 2.不使用var关键字声明会报错 3.严格模式下普通函数的this指向undefined 高阶函数&#xff1a; 满足…

浅谈C/C++指针和引用在Linux和Windows不同环境下的编码风格

目录 0. 前言 1. 代码块、函数体上的 { } 的规范 2. 指针和引用中的 * 和 & 符号的位置 1. Linux 环境下编码风格(gcc) 2. Windows 环境下编码风格(Visual Studio) 3. 简单总结 0. 前言 C/C因为高度的自由性&#xff0c;并没有对一些常见的编码风格进行限制&#…

https://registry.nlark.com/无法访问

先上问题&#xff1a; own up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. npm ERR! code ENOTFOUND npm ERR! syscall getaddrinfo npm ERR! errno ENOTFOU…