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

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。测试结果如下:
在这里插入图片描述
打印结果符合预期,环形队列工作正常。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpreadJS 集成使用案例

SpreadJS 集成案例 介绍&#xff1a; SpreadJS 基于 HTML5 标准&#xff0c;支持跨平台开发和集成&#xff0c;支持所有主流浏览器&#xff0c;无需预装任何插件或第三方组件&#xff0c;以原生的方式嵌入各类应用&#xff0c;可以与各类后端技术框架相结合。SpreadJS 以 纯前…

Java日期和时间(二)

新增的日期和时间 为什么要学习新增的日期和时间 1、代替Calendar LocalDate&#xff1a;年、月、日 LocalTime&#xff1a;时、分、秒 LocalDateTime&#xff1a;年、月、日、时、分、秒 ZoneId&#xff1a;时区 ZoneldDatetime&#xff1a;带时区的时间 2、代替Date Instan…

使用flutter开发一个简单的轮播图带指示器的组件

使用PageView开发一个带指示器的轮播图组件&#xff0c;当轮播图切换的时候&#xff0c;指示器也会跟着切换&#xff0c;切换到当前轮播图所在的索引时&#xff0c;指示器的背景色会变成蓝色&#xff0c;否则是灰色。使用了一个curIndex变量来记录当前激活的轮播图索引。并使用…

HarmonyOS资源分类与访问

资源分类与访问 应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同…

【INTEL(ALTERA)】如何使用quartus设计助理Design Assistant提高结果质量,很好的资料一定要分享!!!

大家在用quartus的时候一定遇到过超级多的警告 warning&#xff0c;甚至异常 error&#xff0c;还有无从下手的timing 。 多扇出&#xff0c;布线拥堵&#xff0c;时序违例是不是让你头疼不已&#xff1f;那你一定要看看这篇文章分享的文档和资料。 优化设计的源代码通常是提高…

CMake入门教程【基础篇】什么是CMakeLists.txt

文章目录 什么是CMakeLists.txtCMakeLists.txt的核心作用CMakeLists.txt的基本结构总结 什么是CMakeLists.txt CMakeLists.txt是一个由CMake&#xff08;一个跨平台的自动化构建系统&#xff09;使用的配置文件。这个文件用于定义软件构建的过程&#xff0c;包括编译源代码、链…

wait 和 notify 这个为什么要在synchronized 代码块中

文章目录 wait 和 notify 这个为什么要在synchronized 代码块中&#xff1f; wait 和 notify 这个为什么要在synchronized 代码块中&#xff1f; wait 和 notify 用来实现多线程之间的协调&#xff0c;wait 表示让线程进入到阻塞状态&#xff0c;notify 表示让阻塞的线程唤醒。…

Vue3+Echarts(柱状图):点击不同的按钮可以切换不同年份的数据

一、需求 在Vue3项目中&#xff0c;绘制一个柱状图&#xff1a; 柱状图会展示某一年里四个季度的销售额提供2个按钮选项&#xff0c;点击不同的按钮可以切换到不同年份的销售额&#xff0c;这里的年份指2022年以及2023年目标效果如下&#xff1a; 默认展示的是2023年的数据&a…

spring 之 事务

1、JdbcTemplate Spring 框架对 JDBC 进行封装&#xff0c;使用 JdbcTemplate 方便实现对数据库操作 1.1 准备工作 ①搭建子模块 搭建子模块&#xff1a;spring-jdbc-tx ②加入依赖 <dependencies><!--spring jdbc Spring 持久化层支持jar包--><dependency&…

病情聊天机器人,利用Neo4j图数据库和Elasticsearch全文搜索引擎相结合

项目设计目的&#xff1a; 本项目旨在开发一个病情聊天机器人&#xff0c;利用Neo4j图数据库和Elasticsearch全文搜索引擎相结合&#xff0c;实现对病情相关数据的存储、查询和自动回答。通过与用户的交互&#xff0c;机器人可以根据用户提供的症状描述&#xff0c;给出初步的可…

论虚继承的作用

虚继承 实验介绍 在上一小节中学习了多继承与多重继承,实际在开发的时候可能会遇到一种情况,既用到了多继承又用到了多重继承,这种继承方式通常又称为菱形继承。但这样一来就会产生新的问题,过多消耗空间。希望通过本小节学习能知道菱形继承以及产生的问题和解决方式。 …

【网络面试(3)】浏览器委托协议栈完成消息的收发

前面的博客中&#xff0c;提到过很多次&#xff0c;浏览器作为应用程序&#xff0c;本身是不具备向网络中发送网络请求的能力&#xff0c;要委托操作系统的内核协议栈来完成。协议栈再调用网卡驱动&#xff0c;通过网卡将请求消息发送出去&#xff0c;本篇博客就来探讨一下这个…

给零基础朋友的编程课09 上集 - 代码

给零基础朋友的编程课09 上 - 矩形、曲线、文字、案例5讲解 上_哔哩哔哩_bilibili 上半Code: / // 彩色案例 艺术仿制品4 // /// 色表 // // 238,150,43 橙 // 229,207,192 暖灰 // 204,50,47 暗红// 项目设定 size(825, 984); // 设置画布(窗口)尺寸 background(…

计算机网络——基础知识汇总(八)

前言&#xff1a; 前面我们已经将计算机网络的基础知识和基础框架有了一个简单的学习与了解&#xff0c;也对它可能考的一些计算机网络计算大题有了一个详细的解答与记录&#xff0c;现在我们将计算机网络中的一些基础知识点进行一个总结与记录&#xff0c;这些基础知识大多会出…

C#编程-编写和执行C#程序

编写和执行C#程序 可以使用Windows记事本应用程序来编写C#程序。在记事本应用程序中创建C#程序后,您需要编译并执行该程序以获得所需的输出。编译器将程序的源代码转换为机器代码,这样计算机就能理解程序中的指令了。 注释 除了记事本,您还可以使用任何其他文本编辑器来编写…

托管在亚马逊云科技的向量数据库MyScale如何借助AWS基础设施构建稳定高效的云数据库

MyScale是一款完全托管于亚马逊云科技&#xff0c;支持SQL的高效向量数据库。MyScale的优势在于&#xff0c;它在提供与专用向量数据库相匹敌甚至优于的性能的同时&#xff0c;还支持完整的SQL语法。以下内容&#xff0c;将阐述MyScale是如何借助亚马逊云科技的基础设施&#x…

ubuntu 20.04 自由切换 python 的版本

问题描述 当前 ubuntu 20.04 默认安装了多个 python 的版本&#xff0c;执行 python 时&#xff0c;默认版本是 Python 2.7.18 zhangszzhangsz:~$ python Python 2.7.18 (default, Jul 1 2022, 12:27:04) [GCC 9.4.0] on linux2 Type "help", "copyright&quo…

AI时代系列丛书(由北京大学出版社出版)

前言 在AI时代&#xff0c;程序员面临着新的机遇和挑战。为了适应这个快速发展的时代&#xff0c;掌握新技能并采取相应的应对策略是至关重要的。 对于办公人员或程序员来说&#xff0c;利用AI可以提高工作效率。例如&#xff0c;使用AI助手可以帮助自动化日常的重复性工作&a…

【flink番外篇】9、Flink Table API 支持的操作示例(8)- 时态表的join(scala版本)

Flink 系列文章 一、Flink 专栏 Flink 专栏系统介绍某一知识点&#xff0c;并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分&#xff0c;比如术语、架构、编程模型、编程指南、基本的…

Spring Cloud Function SpEL注入漏洞(CVE-2022-22963)分析

一、概述 2022年3月24日&#xff0c;Pivotal修补了Spring Cloud Function中一个关键的服务器端代码注入漏洞&#xff08;Spring表达式语言注入&#xff09;&#xff0c;该漏洞有可能导致系统被攻击。Spring是一种流行的开源Java框架&#xff0c;该漏洞与另一个相关的远程代码执…