数据结构:基于数组的环形队列(循环队列)实现

1 前言

队列是一种先进先出的线性表,简称为FIFO。它只允许在队尾插入成员,在队头删除成员,就像现实生活中排队上车一样。
队列的实现可以通过链表或数组完成,一般来说都推荐使用链表来实现队列,使用数组实现队列时每次有新的成员入队都需要对数组其它位置重新赋值,当队列相当大的时候这一过程非常耗时导致效率低下。该过程可以用如下图片表示:
在这里插入图片描述
上面就是一个典型的使用数组实现队列的数据结构,可以看到,每次在队尾插入一个新的成员,需要对整个数组进行赋值。
为了解决常规数组实现队列效率低下的问题,可以将数组修改为环形队列(循环队列)提高效率。

2 环形队列实现

2.1 环形队列结构体

#define MAX_QUEUE_LEN 5
typedef struct
{int head; /* 队列头 */int tail; /* 队列尾 */int memberCnt; /* 队列成员数 */char queueBuff[MAX_QUEUE_LEN]; /* 队列buffer */
} RingQueue_t;

我们这里定义队列头和队列尾指针,用于追踪队列头和队列尾,队列成员数记录当前队列是否存满,队列buffer记录队列成员。

2.2 初始化环形队列

/*** @brief 初始化环形队列* * @param ringQueue 需要初始化的环形队列的地址*/
void init_ring_queue(RingQueue_t *ringQueue)
{ringQueue->head = 0;ringQueue->tail = 0;ringQueue->memberCnt = 0;
}

初始化环形队列非常简单,就是将队列头、队列尾、队列成员数都设置为0,表示当前环形队列为空。

2.3 环形队列成员入队

/*** @brief 环形队列添加一个成员* * @param ringQueue 需要添加一个成员的环形队列的地址* @param member 需要添加的成员*/
void rq_add_member(RingQueue_t *ringQueue, char member)
{ringQueue->memberCnt++;if (ringQueue->memberCnt >= (MAX_QUEUE_LEN + 1)){ringQueue->memberCnt = MAX_QUEUE_LEN + 1;}if (ringQueue->memberCnt <= MAX_QUEUE_LEN){ringQueue->head = 0;ringQueue->tail = MAX_QUEUE_LEN - 1;ringQueue->queueBuff[ringQueue->memberCnt - 1] = member;}else{ringQueue->tail++;if (ringQueue->tail >= MAX_QUEUE_LEN){ringQueue->tail = 0;}ringQueue->queueBuff[ringQueue->tail] = member;ringQueue->head++;if (ringQueue->head >= MAX_QUEUE_LEN){ringQueue->head = 0;}}
}

环形队列成员入队可以分为2个过程:
(1)队列由空到恰好满(无人出队)
(2)队列满(有人出队)

2.3.1 队列由空到恰好满(无人出队)

在这里插入图片描述
如果队列成员计数小于等于队列容量,则将队列头一直设置为0,队列尾一直设置为容量-1。

2.3.2 队列满(有人出队)

在这里插入图片描述
当队列恰好满了时,我们的队列头和队列尾指向了正确的对头、队尾位置。在队列满之后,新成员入队按照先入先出的原则只需要将队尾指针循环右移,然后将入队成员保存到该位置,同时将队头指针循环右移即可。

2.4 查看队列

/*** @brief 查看环形队列成员及数量* * @param ringQueue 需要查看的环形队列的地址*/
void view_ring_queue(RingQueue_t *ringQueue)
{int i, j;if (ringQueue->memberCnt <= MAX_QUEUE_LEN){for (i = 0; i < ringQueue->memberCnt; i++){printf("%02d->", ringQueue->queueBuff[i]);}printf("\r\n");}else{j = ringQueue->head;for (i = 0; i < MAX_QUEUE_LEN; i++){printf("%02d->", ringQueue->queueBuff[j]);j++;if (j >= MAX_QUEUE_LEN){j = 0;}}printf("\r\n");}
}

查看队列需要判断队列成员数,如果成员数小于等于容量,则按照成员数打印,如果成员数大于容量,则根据队头、队尾指示,打印队列所有成员。

3 测试

测试的程序如下:

int main(void)
{int i;RingQueue_t ringQueue;init_ring_queue(&ringQueue);for (i = 1; i < 10; i++){rq_add_member(&ringQueue, i);view_ring_queue(&ringQueue);}
}

按照环形队列的特性,如果工作正常则打印的成员值呈现递增趋势且差值为1。测试结果如下:
在这里插入图片描述
打印结果符合预期,环形队列工作正常。

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

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

相关文章

AI人工智能技术发现了拉斐尔名画背后的秘密:这幅画并非完全由大师本人完成

最近&#xff0c;一个先进的人工智能神经网络在拉斐尔的名画中发现了一个不寻常的地方&#xff1a;其中的一副面孔并非由拉斐尔本人绘制&#xff0c;而是出自其他艺术家之手。 详细文章网址链接&#xff1a;Deep transfer learning for visual analysis and attribution of pai…

07 HAL库ADC读取电压的值

引言&#xff1a; 本文使用adc读取接在SOC的ADC的通道上外设的模拟数据&#xff0c;本文的的实验对象是一个滑动变阻器&#xff0c; 像其它的ADC外设不如光电管&#xff0c; 火焰传感器&#xff0c; 等等一些里的adc设备的根据都是差不多的。 一、ADC的基本知识 ADC&#xff08…

Apache Doris (五十五): Doris Join类型 - Colocation Join

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录 1. Colocation Join原理

苦心分享两款免费AI 绘图软件,效果真的不错

这里写自定义目录标题 图一是 AI 绘画软件一键抠图做的&#xff0c;软件还免费 网址:https://www.yijiankoutu.com/ 一个非常强大的AI绘画网站&#xff0c;能够免费生成各种好看的二次元、3D、国风、漫画、卡通等风格的图片&#xff0c;生成图片跟文字匹配度非常高&#xff0c;…

【Qt之Quick模块】6. QML语法详解_3 QML对象特性

概述 每一个QML对象类型都包含一组已定义的特性。当进行实例时都会包含一组特性&#xff0c;这些特性是在对象类型中定义的。 一个QML文档中的对象类型声明了一个新的类型&#xff0c;即实例出一个类型。 其中包含以下特性。 the id attribute &#xff1a; id特性property a…

Node.js使用jemalloc内存分配器显著减少内存使用

前言 Node.js 默认使用的是 ptmalloc(glibc) 内存分配器&#xff0c;而&#xff1a; 在服务端领域「不会选择默认的 malloc」是一个常识。&#xff08; 来源 &#xff09; ptmalloc 的分配效率较低&#xff08; 来源 &#xff09;&#xff0c;对于 长时间、多核 / 多线程 运行…

lvm建立卷组和扩容

一、逻辑卷lvm 1.可以动态扩容 pe是逻辑卷最小的存储单元&#xff0c;最小4k 1.物理卷 将硬盘转化成 pe 2.卷组 将pe分组&#xff0c;一个逻辑卷只可以用一个组里面的pe 3.逻辑卷 类似于分区 1.1分区类型 lvm 如果使用分区&#xff0c;要修改分区类型为8e 二、…

Nacos身份认证权限绕过+漏洞利用工具分享

目录 一 JWT JWT: JWT的使用场景&#xff1a; JWT构造&#xff1a; 二 漏洞描述&#xff1a; 三 环境搭建 四 漏洞复现 五 工具漏洞复现 六 修复建议 七 工具分享 本文由掌控安全学院 - 小博 投稿 一 JWT JWT: JSON Web Token (JWT)是一个开放标准(RFC 7519)&…

【JAVA】实验一 从面向过程到面向对象

实验名称 实验一 从面向过程到面向对象 实验目的 1. 掌握Java语言简单数据类型、表达式、输入输出&#xff1b; 2. 理解Java类中main方法的编写及过程化编程&#xff1b; 3. 掌握Java数组的使用。 实验内容 1. 输入年份&#xff0c;判断是否是闰年。闰年…

看懂基本的电路原理图(入门)

文章目录 前言一、二极管二、电容三、接地一般符号四、晶体振荡器五、各种符号的含义六、查看原理图的顺序总结 前言 电子入门&#xff0c;怎么看原理图&#xff0c;各个图标都代表什么含义&#xff0c;今天好好来汇总一下。 就比如这个电路原理图来说&#xff0c;各个符号都…

【Linux C | 文件I/O】文件数据的同步 | sysc、fsync 和 fdatasync 函数

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

[每周一更]-(第47期):Go业务发展方向

Go业务方向 Go&#xff08;也称为Golang&#xff09;是一种开源编程语言&#xff0c;具有简洁、高效和并发性等特点&#xff0c;逐渐在业界流行起来。Go语言在不同领域有着广泛的应用&#xff0c; 下面列举了一些Go语言的业务发展方向&#xff1a; Web开发&#xff1a;Go语言…