98.【C语言】数据结构之队列

目录

1.定义

2.队头和队尾

3.示意图

4.实现队列

两种解决方法

1.使用双向带头循环链表

2.为单向链表再定义一个尾指针tail

操作队列的函数 

初始化函数QueueInit

插入函数QueuePush

删除函数QueuePop

写法1

注意

写法2

计算队列大小函数QueueSize

销毁函数QueueDestroy 


1.定义

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

2.队头和队尾

:进行删除(即出队Dequeue)操作的一端

:进行插入(即入队Enqueue)操作的一端

注意到:由于队列的特性,删除只在队头,插入只在队尾(这里和链表不一样:链表支持头删、尾删、头插和尾插)

特点:FIFO(First In First Out)先进先出

3.示意图

6376208b5e584062a1e2d56559f33fea.png

这里比较像链表的尾插

4.实现队列

main函数的第一行代码

QNode* head = NULL;

如果频繁尾插,会导致找尾麻烦,因此不建议这样写,

两种解决方法

1.使用双向带头循环链表

有关双向带头循环链表的内容参见

94.【C语言】数据结构之双向链表的初始化,尾插,打印和尾删

95.【C语言】数据结构之双向链表的头插,头删,查找,中间插入,中间删除和销毁函数

2.为单向链表再定义一个尾指针tail

Queue.h写入

typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

除了有头指针和尾指针之外,还要用变量size来存储队列的大小

再用一个结构体去定义队列中的每一个节点

typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

这里和以往的链表的定义不一样,用两个结构体来定义 ,将头指针,尾指针和size打包成结构体是为了方便操作

画图则为:

操作队列的函数 

初始化函数QueueInit

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

一开始队列一个元素都没有插入,因此head和tail全部置NULL,队列大小size为0

插入函数QueuePush

每插入一个节点需要做两件事:

1.开辟节点并写入节点(节点指针和节点值)

做法:malloc开辟空间,检查空间是否成功开辟,再用newnode接收新开辟空间的起始地址,

2.修改结构体Queue的成员变量

注意:如果一开始队列中一个节点都没有,不能直接尾插,否则导致pq->tail->next = newnode;和pq->tail = newnode;变为NULL->next = newnode;和NULL = newnode;不合法

如果为NULL,做的操作应该是头指针和尾指针都应该指向newnode,size++而不是去尾插

队列中有节点,直接为插,size++

void QueuePush(Queue* pq, QDataType x)
{
//开辟节点并写入节点(节点指针和节点值)
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc");
		return;
	}
	newnode->data = x;
	newnode->next = NULL;

//---------------------------------------------------

//修改结构体Queue的成员变量
	if (pq->head == NULL)
	{
		assert(pq->tail == NULL);
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

删除函数QueuePop

队列的性质只支持

写法1
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head != NULL);

	QNode* next = pq->head->next;
	free(pq->head);
	pq->head = next;
	if (pq->head == NULL)
		pq->tail = NULL;

    pq->size--;
}
注意

1.队列不能头删,因此断言assert(pq->head != NULL);

2.头删要先保存头节点的下一个节点的地址,之后free(头结点的地址)

3.如果头删后没有节点,则投头指针和尾指针都要赋值为NULL

写法2
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head != NULL);

	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}

	pq->size--;
}

计算队列大小函数QueueSize

由于提前创建好了结构体Queue,则直接返回size即可

void QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

销毁函数QueueDestroy 

void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
		pq->head = pq->tail = NULL;
		pq->size = 0;
}

1.由于malloc是以节点为单位开辟空间的,则内存释放时也要以节点为单位释放,因此内存释放要先保存头节点的下一个节点的地址,之后free(头结点的地址)

2.恢复头指针,尾指针和size的初始值

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

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

相关文章

SQL项目实战与综合应用——项目设计与需求分析

项目设计与需求分析是软件开发过程中的核心环节,尤其在涉及数据库的应用时,良好的设计将直接影响到项目的可扩展性、性能和维护性。本文将深入探讨数据库设计的最佳实践,结合 C 与 SQL 的实际应用场景,涵盖项目需求收集、数据库设…

TCP的“可靠性”(下)——三次握手四次挥手

目录 建立连接(三次握手)为啥要进行握手??意义何在??常见面试题:为啥必须是三次握手? 断开连接(四次挥手)三次握手和四次挥手的相同点和不同点连接过程中涉及…

煤矿 35kV 变电站 3 套巡检机器人 “上岗”,力破供电瓶颈

近日,杭州旗晟智能科技与甘肃陈家沟煤矿35kV变电站配电室的三套智能巡检机器人线下测试顺利完成,并成功交付使用,这为陈家沟煤矿的电力运维工作注入了全新的活力与强大的技术支撑。 一、项目背景 甘肃陈家沟煤矿35kV变电站于2024年3月13日动…

【AI系统】推理参数

推理参数 本文将介绍 AI 模型网络参数方面的一些基本概念,以及硬件相关的性能指标,为后面让大家更了解模型轻量化做初步准备。值得让人思考的是,随着深度学习的发展,神经网络被广泛应用于各种领域,模型性能的提高同时…

列表| 习题+思维导图

列表习题 1. 已知列表xlist(range(9)),那么执行语句del x[:2]之后,x的值为(D) A.[1,3,5,7,9] B.[1,3,5,7] C.[0,1,3&a…

在freeBSD上开启IPSec内核功能

我使用的版本strongSwan 6.0.0, FreeBSD 14.1-RELEASE, amd64 背景 在freeBSD上配置strongSwan,启动charon时,一直遇到如下错误: unable to set IPSEC_POLICY on socket: Protocol not available过程 此前查阅的某个文档说 freeBSD已经默…

初识树(二叉树,堆,并查集)

本篇博客将涉及到一些专业名词:结点、深度、根、二叉树、满二叉树、完全二叉树、堆、并查集等。 概要 树型结构是一类重要的非线性数据结构。其中以树和二叉树最…

知从科技闪耀汽车智能底盘大会:共探软件安全新篇章

在汽车科技蓬勃发展的浪潮中,智能底盘技术正成为引领行业变革的关键力量。11月27日-28日,盖世汽车 2024 第四届汽车智能底盘大会盛大召开,上海知从科技有限公司受邀出席此次盛会,与众多汽车领域的精英齐聚一堂,共话智能…

TCP Analysis Flags 之 TCP Spurious Retransmission

前言 默认情况下,Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态,并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时,会对每个 TCP 数据包进行一次分析,数据包按照它们在数据包列表中出现的顺序进行处理。可…

241205_使用本地vosk模型实现流式语音识别

241205_使用本地vosk模型实现流式语音识别 上一篇我们使用了vosk模型实现了本地的语音识别,但是存在一个严重的问题,因为我们采用的是整段音频录制结束之后再进行转文字并进行关键字检索,就会导致识别不实时,在环境噪音较为复杂&…

CMake笔记之在CMakeLists.txt文件中开启Debug模式

CMake笔记之在CMakeLists.txt文件中开启Debug模式 code review! 文章目录 CMake笔记之在CMakeLists.txt文件中开启Debug模式1.设置 CMake 的构建类型2.添加编译器的调试选项3.使用 CMAKE_CXX_STANDARD (可选)4.编译和构建5.针对多配置生成器6.最终示例 CMakeLists.txt 1.设置 …

VINS_MONO视觉导航算法【一】基础知识介绍

文章目录 VINS-Mono其他文章说明简介单目相机存在的尺度不确定问题缺乏深度信息尺度等价性对极几何和三角化平移和深度的关系解决尺度不确定问题的方法视觉惯性里程计(VIO)初始尺度估计持续尺度校正 摄像头数据处理直接法(Direct Method&…

【CC2530开发基础篇】光敏和热敏传感器

一、前言 1.1 开发背景 本实验通过CC2530单片机接入光敏传感器和热敏传感器,进行数据采集与检测,并将检测结果通过串口终端输出。光敏传感器和热敏传感器是常见的环境感知设备,分别用于测量光强和温度。在实际应用中,这些传感器…

计算机网络-GRE基础实验二

前面我们学习了GRE隧道的建立以及通过静态路由指向的方式使得双方能够网络互联,但是通过静态路由可能比较麻烦,GRE支持组播、单播、广播因此可以在GRE隧道中运行动态路由协议使得网络配置更加灵活。 通过前面的动态路由协议的学习我们知道动态路由协议都…

中建海龙:科技创新引领建筑业革新,铸就行业影响力

在建筑业这个古老而又充满活力的行业中,中建海龙科技有限公司(以下简称“中建海龙”)凭借其卓越的科技实力和一系列荣誉奖项,正逐步确立其在建筑工业化领域的领导地位,并对整个行业产生了深远影响。 中建海龙自成立以来…

Y20030028 JAVA+SSM+MYSQL+LW+基于JAVA的考研监督互助系统的设计与实现 源代码 配置 文档

基于JAVA的考研监督互助系统 1.项目描述2. 课题开发背景及意义3.项目功能4.界面展示5.源码获取 1.项目描述 随着高等教育的普及和就业竞争的加剧,越来越多的学生选择继续深造,参加研究生入学考试。考研人数的不断增加,使得考研过程中的学习监…

HarmonyOS NEXT开发进阶(一):初识 HarmonyOS NEXT开发

文章目录 一、前言二、HarmonyOS NEXT 开发框架三、HarmonyOS NEXT开发指导3.1 Windows环境准备 四、项目拆解4.1 工程目录4.2 全局配置4.2.1 APP全局配置: AppScope层(AppScope/app.json5)4.2.3 签名全局配置 4.3 APP代码初始化4.4 APP签名文件配置4.5 …

【机器学习算法】——逻辑回归

目录 逻辑回归理解损失函数代码练习1. 房屋价格与面积的关系2.基于学生特征的录取概率预测 逻辑回归理解 逻辑回归是用来二分类的! 是在线性回归模型之后加了一个激活函数(Sigmoid)将预测值归一化到【0~1】之间,变成概率值。 一般计算其中一…

mongo开启慢日志及常用命令行操作、数据备份

mongo开启慢日志及常用命令行操作、数据备份 1.常用命令行操作2.mongo备份3.通过命令临时开启慢日志记录4.通过修改配置开启慢日志记录 1.常用命令行操作 连接命令行 格式:mongo -u用户名 -p密码 --host 主机地址 --port 端口号 库名; 如:连…

排序的事

排序的事 C语言实现C实现Java实现Python实现 💐The Begin💐点点关注,收藏不迷路💐 输入n个不相同的正整数,每个数都不超过n。现在需要你把这些整数进行升序排序,每次可以交换两个数的位置,最少需…