C语言队列的含义与队列数据操作代码详解!

引言:于本篇博客当中,我们将讲到数据结构——队列的有关知识。而对于这次的队列,我们将会在单链表的基础上实现。

更多有关C语言和数据结构知识详解可前往个人主页:计信猫

一,队列的含义

        队列是一种特殊的线性表,它只允许在表的一端进行插入数据的操作,另一端进行删除数据的操作

队头:进行数据删除的一端

队尾:进行数据插入的一端

        所以,队列便可以用如下的图进行表示:

         而正因为队列遵循FIFO原则(即先进先出),使得入队列出队列的顺序一一对应,也就多被应用于广度优先遍历的操作。

二,队列结构体的定义

        老样子,我们仍然使用三文件操作法,分别创建Queue.h、Queue.c、test.c三个文件。

        因为先前提到,队列会在单链表的基础上实现,那么我们就需要先定义一个单链表结构体

typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;

        但是,因为在队列之中,我们只需要关注队列队头队尾的两个节点即可,并且为了避免二级指针的使用难以理解,所以我们选择再定义一个结构体Queue用于储存队列队头队尾两节点

typedef struct Queue
{QNode* phead;QNode* ptail;int size;//记录队列中的节点个数
}Queue;

        包含可能用到的头文件后,我们的Queue.h的代码内容如下:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;
typedef struct Queue
{QNode* phead;QNode* ptail;int size;//记录队列中的节点个数
}Queue;

三,队列数据操作函数

1,队列的初始化

        队列的初始化其他数据结构的初始化别无它异,我们只需要将结构体中的指针类型初始化为NULL整型类型初始化为0就可以了。直接上代码:   

// 初始化队列 
void QueueInit(Queue* q)
{assert(q);q->phead = q->ptail = NULL;q->size = 0;
}

2,队列的尾插

        对于队列的尾插,其实也就和单链表的尾插一模一样。我们只需要使用malloc函数申请一个节点的空间,然后将新创建的节点连在队列的尾部,同时将ptail指针移到新形成的队尾,最后的最后,一定不要忘记size++。这样,一个队列的尾插函数就成功写出了。

// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));//创建新节点if (newnode == NULL){perror("malloc fail!");return;}newnode->next = NULL;newnode->val = data;//队列元素为0个时if (q->ptail == NULL){q->phead = q->ptail = newnode;}//队列有元素时else{q->ptail->next = newnode;q->ptail = newnode;}q->size++;
}

3,队列的头删

        因为队列只可以在队头进行数据删除,所以队列就只有一个头删函数

        如上图所示,对于队列的头删函数,我们需要首先创建节点结构体指针next记录队头的下一个节点的地址,以免队头free掉之后导致的后续节点的丢失,然后我们再将phead指针赋值为next,最后再进行size--即可

        但是有一个特殊情况,当队列只有一个节点的时候,我们进行队列的头删之后,ptail则会变成野指针,这时候我们就需要特殊处理,将ptail也赋值为NULL,防止野指针的出现。如图:

         综上所述,我们的队列头删函数如下: 

// 队头出队列 
void QueuePop(Queue* q)
{assert(q);assert(q->size > 0);QNode* next = q->phead->next;free(q->phead);q->phead = next;//特殊情况:队列只有一个节点的时候if (q->phead == NULL){q->ptail = NULL;}//勿忘size--q->size--;
}

4,获取队列头部数据

        这时候,我们所创建的Queue结构体就派上大用场了,因为这个结构体直接就保存了我们的phead节点,所以我们直接使用就可以了。代码如下:

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);assert(q->phead);return q->phead->val;
}

5,获取队列尾部数据 

        那么这个函数,也就跟前一个函数相差不大了。都是直接使用Queue结构体就可以了,我们直接上代码:

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);assert(q->ptail);return q->ptail->val;
}

6,获取队列有效元素个数 

        在Queue结构体中,我们早就使用了size来记录有效元素的个数,所以我们直接返回size的值即可。

// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);return q->size;
}

7,判断队列是否为空 

        该函数的返回值为布尔类型,即truefalse

队列为空,返回:true

队列不为空,返回:false

        对于队列是否为空,我们只需要判断size是否为零就可以了。所以代码如下:

// 检测队列是否为空
bool QueueEmpty(Queue* q)
{assert(q);return q->size == 0;//若size等于零,则表达式为真,则队列为空//若size不等于零,则表达式为假,则队列为假
}

8,队列的销毁 

         因为我们创建队列时使用了malloc函数,故为了防止内存溢出,我们需要创建一个队列的销毁函数,来完成释放队列申请的空间的操作。

        在该函数中,我们需要再创建一个QNode结构体指针cur用于保存即将被释放的节点的下一个节点的地址,以防止地址的丢失,然后再使用free函数释放掉节点即可。最后的最后,勿忘将size置为零

        所以我们的代码如下:

// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);QNode* next = q->phead;while (next){QNode* cur = next->next;free(next);cur = next;}q->size = 0;
}

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

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

相关文章

使用 SSH 连接 GitHub Action 服务器

前言 Github Actions 是 GitHub 推出的持续集成 (Continuous integration&#xff0c;简称 CI) 服务它提供了整套虚拟服务器环境&#xff0c;基于它可以进行构建、测试、打包、部署项目&#xff0c;如果你的项目是开源项目&#xff0c;可以不限时使用服务器硬件规格&#xff1…

DrissionPage

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;本文章未经许…

Java请求第三方接口的一些步骤

一、前言 Java请求第三方接口的一些步骤。 在Java中请求第三方接口通常涉及以下步骤。这些步骤涵盖了从准备请求到处理响应的整个过程。 1. 确定接口详情 接口URL&#xff1a;你要请求的URL。请求方法&#xff1a;如GET、POST、PUT、DELETE等。请求参数&#xff1a;包括URL…

微型显示器可以实时监测大脑活动

美国团队开发基于LED的设备&#xff0c;以可视化大脑活动&#xff0c;在脑外科手术中指导神经外科医生 来自加州大学圣地亚哥分校和马萨诸塞州总医院的工程师和医生开发了一种薄膜显示设备&#xff0c;该设备结合了电极网格和特殊的GaN LED&#xff0c;可以在手术过程中实时跟…

多线程学习Day07

共享模型之不可变 从一个日期转换的问题开始 Slf4j(topic "c.Test1") public class Test1 {public static void main(String[] args) {SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd");for (int i 0; i < 10; i) {new Thread(() -> {…

buuctf-misc题目练习二

ningen 打开题目后是一张图片&#xff0c;放进winhex里面 发现PK&#xff0c;PK是压缩包ZIP 文件的文件头&#xff0c;下一步是想办法进行分离 Foremost可以依据文件内的文件头和文件尾对一个文件进行分离&#xff0c;或者识别当前的文件是什么文件。比如拓展名被删除、被附加…

元素设置 flex:1,但是会被内部长单词宽度超出拉伸

初始布局如上图&#xff0c;left中是代码编辑器&#xff0c;实际上是个文本域&#xff0c;当输入长文本过长时&#xff0c;left宽度会被拉伸。 右侧容器被挤压。 解决方案&#xff1a;width&#xff1a;0&#xff1b; .left{flex:1; width:0} 当输入长文本过长时&#xff0c…

保姆级零基础微调大模型(LLaMa-Factory,多卡版)

此处非常感谢https://github.com/hiyouga/LLaMA-Factory这个项目。 看到网上的教程很多都是教如何用webui来微调的,这里出一期命令行多卡微调教程~ 1. 模型准备 模型下载比较方便的方法: 1. modelscope社区(首选,速度很高,并且很多需要申请的模型都有)注意要选择代码…

HTML4(二)

文章目录 1 开发者文档2 基本标签2.1 排版标签2.2 语义化标签2.3 行内元素与块级元素2.4 文本标签2.5 常用标签补充 3 图片标签4 超链接标签4.1 跳转页面4.2 跳转文件4.3 跳转锚点4.4 唤起指定应用 5 列表5.1 有序列表5.2 无序列表5.3 自定义列表 6 表格6.1 基本结构6.2 表格标…

【Android】Kotlin学习之数据容器(数组创建)

kotlin数组 数组是一种初始化时指定容器大小, 不可以动态调整其大小的容器 数组创建

WPF之改变任务栏图标及预览

1&#xff0c;略缩图添加略缩按钮。 <Window.TaskbarItemInfo><TaskbarItemInfo x:Name"taskInfo" ProgressState"None" ProgressValue"0.6" ><TaskbarItemInfo.ThumbButtonInfos><ThumbButtonInfo x:Name"btiPlay&q…

雷伴品鉴【神农式】倪琴 倪诗韵古琴

雷伴品鉴【神农式】倪琴 倪诗韵古琴 此琴材质为老杉木音色细腻&#xff0c;下指按弹舒适&#xff0c;手感极好漆面精美&#xff0c;线条流畅。

OpenCV4.8 VS2019 MFC编程出现的诡异现象

OpenCV4.8及OpenCV4.4 VS2019MFC编程在调用imred&#xff08;&#xff09;函数时&#xff0c;debug X64试运行没问题。 release X64试运行时出现下面错误。 void CEasyPictureDlg::OnBnClickedOpen() {CFileDialog fdlg(TRUE, NULL, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMP…

私人健身教练预约管理小程序开发源码现成案例(小程序+APP+H5 源码部署)

一、私人健身教练预约管理系统-环境介绍 1.1 私人健身教练预约管理系统-运行环境 开发语言&#xff1a;PHP 数据库&#xff1a;MySQL 系统架构&#xff1a;TP 后端&#xff1a;SpringBoot 前端&#xff1a;Vue 2. 私人健身教练预约管理系统-系统介绍。 2.1私人健身教练预约管…

EasyExcel导出带自定义下拉框数据的Excel模板

文章目录 前言&#x1f4dd;一、导入依赖二、创建导出工具1.创建模板实体类2.创建自定义注解3.添加动态选择接口4.EasyExcelUtil工具类 三、导出、导入Excel接口1.导出接口2.导入接口3.导出结果 总结 前言&#x1f4dd; 在项目中导入excel时需要通过下拉框选择值传入&#xff…

【websocket-客户端可视化工具】

postman 新版postman (版本v11以上) &#xff0c;除了http协议&#xff0c;还支持了Websocket&#xff0c;MQTT&#xff0c;gRPC等多种连接协议&#xff0c;可以作为多种协议的客户端&#xff0c;使用起来非常方便。 使用 服务端代码 这里以websocket协议举例&#xff0c;代…

基于51单片机的八路抢答器—加随机抽选功能

基于51单片机的八路抢答器 &#xff08;仿真&#xff0b;程序原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.主持人按键控制开始抢答&#xff1b; 2.开始抢答按下&#xff0c;数码管20秒倒计时&#xff1b; 3.8个按键代表八位选手&#xff0c;谁…

视频降噪算法 hqdn3d 原理分析

视频降噪 视频降噪是一种处理技术&#xff0c;旨在减少视频中的噪声&#xff0c;提高画面质量。噪声可能来自多种源头&#xff0c;包括摄像机的传感器、压缩算法、传输过程中的干扰等。降噪处理对于视频监控、视频会议、电影后期制作以及任何需要高画质输出的应用场景都非常重…

今天又发现一个有意思的问题:SQL Server安装过程中下载报错,证明GPT是可以解决问题的

我们在安装数据库的时候&#xff0c;都会有报错问题&#xff0c;无论是Oracle、SQL Server、还是MySQL&#xff0c;都会遇到各种各样的报错&#xff0c;这归根到底还是因为电脑环境的不同&#xff0c;和用户安装的时候&#xff0c;操作习惯的不一样导致的问题。今天的问题是&am…

SwiftUI 5.0(iOS 17.0,macOS 14.0+)新 Inspector 辅助视图之趣味漫谈

概览 在 SwiftUI 开发中,苹果为我们提供了多种辅助视图用来显示额外信息从而极大丰富了应用的表现力,比如:Alert、Sheet、ContextMenu 等等。 从 SwiftUI 5.0(iOS 17+)开始, 又增加了一种全新的辅助视图:Inspector。 在本篇博文中,您将学到如下内容: 概览1. Inspe…