数据结构 队列(C语言实现)

news2024/12/24 20:10:40

绪论

        任其事必图其效;欲责其效,必尽其方。——欧阳修;本篇文章主要写的是什么是队列、以及队列是由什么组成的和这些组成接口的代码实现过程。(大多细节的实现过程以注释的方式展示请注意查看

 话不多说安全带系好,发车啦(建议电脑观看)


附:红色,部分为重点部分;蓝颜色为需要记忆的部分(不是死记硬背哈,多敲);黑色加粗或者其余颜色为次重点;黑色为描述需要


目录

队列

1.队列的实现​编辑

1.1队列的结构

1.2队列的初始化

1.3将数据放进队列中

1.4删除数据

1.5查看队列中是否有数据

1.6查看队列中的头尾数据

1.7查看队列中有几个元素

1.8队列的摧毁

2.队列的实现代码


队列

知识点:

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)

入队列:进行插入操作的一端称为队尾 、出队列:进行删除操作的一端称为队头

细节:

队列的基本结构框架:同样队列也是既能由顺序表也能由链表来实现的,下面将用链表来实现(因为链表相较于顺序表来说,其头删的效率比较高)

  1. 队列的结构
    1. 指向链表头的指针
    2. 指向链表尾的指针
    3. 记录链表元素个数的变量
  2. 队列所要实现的功能
    1. 队列的初始化
    2. 队列的摧毁
    3. 放入数据
    4. 删除数据
    5. 查看队列是否为空
    6. 获取头部、尾部的数据
    7. 查看队列中有几个元素

1.队列的实现

1.1队列的结构

因为队列是由链表来实现所以先要有一个链表,然后队列中的结构由指向链表的头和尾的指针以及一个记录链表中有多少数据的变量。

所以我们就分成两个结构体的形式:一个结构体实现单链表,一个结构体是队列的结构queue。

typedef int QDataType;

typedef struct QListNode
{
	struct QListNode* _pNext;//指向下一个
	QDataType _data;//数据
}QNode;

typedef struct Queue
{
	QNode * _front;//指向头
	QNode* _rear;//尾
	int _size;//记录有几个数据
}Queue;

1.2队列的初始化

初始化一下队列,把队列中的两个指针已经记录数据个数的变量初始化

void QueueInit(Queue* q)//用指针接收结构
{
	assert(q);//判空
	q->_front = q->_rear = NULL;//连续赋值将两个指针都先赋值成空指针
	q->_size = 0;//一开始元素个数为0
}

1.3将数据放进队列中

将数据放进队列中,其实原理类似实现链表的尾插,不同于主要是通过rear来找到尾,然后直接进行数据的插入(当rear为NULL时表示队列中是没有数据的

void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* pf = (QNode*)malloc(sizeof(QNode));//先申请一个链表节点空间
	if (pf == NULL)//判断是否申请成功
	{
		perror("malloc");
		return;
	}
	//判断第一个节点是否存在(队列中没有数据的时候rear是NULL)
	if (q->_rear)//若不为NULL
	{
		q->_rear->_pNext = pf;//进行尾插,也就是在最后一个节点后面插入新生成的节点pf
		q->_rear = pf;//再把尾部修改一下
	}
	else//当队列中没有数据的时候
	{
		//此时把头和尾指针都指向pf这样就创建好链表的开始了
		q->_rear = pf;
		q->_front = pf;
	}
	q->_rear->_data = data;//将rear指向后,将尾部的数据填充为所给的data
	q->_rear->_pNext = NULL;//再将尾部指针的下一个位置置成NULL
	q->_size++;//元素个数++
}

1.4删除数据

删除数据就相当于链表的头删,通过front找到头进行释放,然后再改变一下front头,注意队列中是否有数据

void QueuePop(Queue* q)
{
	assert(q);//判空
	assert(!QueueEmpty(q));//查看队列中是否有数据
	QNode* tmp = q->_front->_pNext;//用tmp记录一下第二个位置的数据的地址
	if (q->_front == q->_rear)//判断一下是否为最后一个元素
	{
		free(q->_front);//释放头指向的空间
		//若是则直接吧rear和front都置为NULL
		q->_front = q->_rear = NULL;
	}
	else//反之当不止只有一个数据时
	{
		free(q->_front);//同样是否头位置的空间

		q->_front = tmp;//改变一下头位置然其指向第二个数据的位置也就是新头
	}
	q->_size--;//元素减少一位
}

1.5查看队列中是否有数据

直接查看一下size即可

bool QueueEmpty(Queue* q)
{
	assert(q);//判空
	return q->_size == 0;//查看size是否为0,若为则返回真(1)反之则为假(0)
}

1.6查看队列中的头尾数据

直接返回各指针指向空间的数据,注意要判断一下是否为空(否则可能会访问到NULL)

QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));//判断队列是否有数据
	return q->_front->_data;//返回头位置的数据
}

QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));//判断队列是否有数据
	return q->_rear->_data;//返回尾位置的数据
}

1.7查看队列中有几个元素

直接返回队列结构体中的size即可


int QueueSize(Queue* q)
{
	return q->_size;//返回size即可
}

1.8队列的摧毁

队列的摧毁和链表的摧毁几乎一样

void QueueDestroy(Queue* q)
{
	assert(q);
	//从前往后的进行各链表节点释放
	while (q->_front)//判断头是否为空
	{
		QNode* next = q->_front->_pNext;//用next记录下一个位置的地址(防止找不到)
		free(q->_front);//释放当前位置
		q->_front = next;//让front指向下一个位置
	}
	q->_front = q->_rear = NULL;//链表数据全部释放完后把front/rear也置为NULL
	q->_size = 0;//把size置为0
}

2.队列的实现代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>


typedef int QDataType;

typedef struct QListNode
{
	struct QListNode* _pNext;//指向下一个
	QDataType _data;//数据
}QNode;

typedef struct Queue
{
	QNode * _front;//头
	QNode* _rear;//尾
	int _size;
}Queue;




void QueueInit(Queue* q)
{
	assert(q);
	q->_front = q->_rear = NULL;
	q->_size = 0;
}

void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* pf = (QNode*)malloc(sizeof(QNode));//先申请一个链表节点空间
	if (pf == NULL)//判断是否申请成功
	{
		perror("malloc");
		return;
	}
	//判断第一个节点是否存在(队列中没有数据的时候rear是NULL)
	if (q->_rear)//若不为NULL
	{
		q->_rear->_pNext = pf;//进行尾插,也就是在最后一个节点后面插入新生成的节点pf
		q->_rear = pf;//再把尾部修改一下
	}
	else//当队列中没有数据的时候
	{
		//此时把头和尾指针都指向pf这样就创建好链表的开始了
		q->_rear = pf;
		q->_front = pf;
	}
	q->_rear->_data = data;//将rear指向后,将尾部的数据填充为所给的data
	q->_rear->_pNext = NULL;//再将尾部指针的下一个位置置成NULL
	q->_size++;//元素个数++
}

bool QueueEmpty(Queue* q)
{
	assert(q);
	return q->_size == 0;//查看size是否为0,若为则返回真(1)反之则为假(0)
}
void QueuePop(Queue* q)
{
	assert(q);//判空
	assert(!QueueEmpty(q));//查看队列中是否有数据
	QNode* tmp = q->_front->_pNext;//用tmp记录一下第二个位置的数据的地址
	if (q->_front == q->_rear)//判断一下是否为最后一个元素
	{
		free(q->_front);//释放头指向的空间
		//若是则直接吧rear和front都置为NULL
		q->_front = q->_rear = NULL;
	}
	else//反之当不止只有一个数据时
	{
		free(q->_front);//同样是否头位置的空间

		q->_front = tmp;//改变一下头位置然其指向第二个数据的位置也就是新头
	}
	q->_size--;//元素减少一位
}

QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));//判断队列是否有数据
	return q->_front->_data;//返回头位置的数据
}

QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));//判断队列是否有数据
	return q->_rear->_data;//返回尾位置的数据
}

int QueueSize(Queue* q)
{
	return q->_size;//返回size即可
}

void QueueDestroy(Queue* q)
{
	assert(q);
	//从前往后的进行各链表节点释放
	while (q->_front)//判断头是否为空
	{
		QNode* next = q->_front->_pNext;//用next记录下一个位置的地址(防止找不到)
		free(q->_front);//释放当前位置
		q->_front = next;//让front指向下一个位置
	}
	q->_front = q->_rear = NULL;//链表数据全部释放完后把front/rear也置为NULL
	q->_size = 0;//把size置为0
}

如果有任何问题欢迎讨论哈!

如果觉得这篇文章对你有所帮助的话点点赞吧!

持续更新大量数据结构细致内容,早关注不迷路。

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

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

相关文章

Python3,关于请求重试,这次requests库给安排的明明白白。

requests库重试请求 1、引言2、requests库2.1 安装2.2 代码实例2.2.1 重试次数设置2.2.2 重试条件设置2.2.3 超时时间设置 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c; 你看这是啥&#xff1f; 小鱼&#xff1a;我瞅瞅… 小屌丝&#xff1a;鱼哥&#xff0c;你这眼神…

【计算机视觉】Fast Segment Anything 安装步骤和示例代码解读(含源代码)

文章目录 一、导读二、安装步骤2.1 将存储库克隆到本地2.2 创建 conda 环境2.3 安装软件包2.4 安装 CLIP2.5 下载权重文件2.6 开始使用2.6.1 Everything mode2.6.2 Text prompt2.6.3 Box prompt (xywh)2.6.4 Points prompt 三、示例代码 一、导读 论文地址&#xff1a; https:…

服务器配置与操作

服务器配置与操作 一、连接远程服务器 推荐用xshell 或者 finalshell 或者 winSCP 或者 FileZilla xshell下载地址&#xff1a;https://xshell.en.softonic.com/ 二、服务器配置 2.1 安装JDK 2.1 方法一&#xff1a;在线安装 yum list java* yum -y install java-1.8.0-ope…

【Django | 爬虫 】收集某吧评论集成舆情监控(附源码)

&#x1f935;‍♂️ 个人主页: 计算机魔术师 &#x1f468;‍&#x1f4bb; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 文章目录 一、爬取帖子、二级评论二、构建数据表三、并入项目1. spider代码2. view视图代码3. 优化后台界面3. urls路由 四、定…

第二十三章Java二维数组详解

一、创建二维数组 在 Java 中二维数组被看作数组的数组&#xff0c;即二维数组为一个特殊的一维数组&#xff0c;其每个元素又是一个一维数组。Java 并不直接支持二维数组&#xff0c;但是允许定义数组元素是一维数组的一维数组&#xff0c;以达到同样的效果。声明二维数组的语…

编程规范-控制流程、错误和异常处理

前言&#xff1a; \textcolor{Green}{前言&#xff1a;} 前言&#xff1a; &#x1f49e;这个专栏就专门来记录一下寒假参加的第五期字节跳动训练营 &#x1f49e;从这个专栏里面可以迅速获得Go的知识 今天的笔记是对编程规范的补充&#xff0c;对控制流程、错误和异常处理进行…

Ansys Zemax | 内窥镜物镜系统初始结构的优化提升(下)

系统性能提升 根据上篇的内窥镜系统分析&#xff0c;我们可以从四个方面对内窥镜物镜系统进行优化&#xff1a;元件间距、圆锥系数、MTF 值以及畸变值。点击优化-评价函数编辑器以设置具体的评价函数。&#xff08;联系我们获取文章附件&#xff09; 首先&#xff0c;用三个 CO…

NXP i.MX 8M Plus工业开发板硬件说明书--下册( 四核ARM Cortex-A53 + 单核ARM Cortex-M7,主频1.6GHz)

前 言 本文档主要介绍创龙科技TLIMX8MP-EVM评估板硬件接口资源以及设计注意事项等内容。 创龙科技TLIMX8MP-EVM是一款基于NXP i.MX 8M Plus的四核ARM Cortex-A53 单核ARM Cortex-M7异构多核处理器设计的高性能工业评估板&#xff0c;由核心板和评估底板组成。ARM Cortex-A5…

【AndroidUI设计】Bottom Navigation Activity中Fragment(碎片)的添加和下层导航图标的修改

文章目录 一、引言二、设计1、添加Fragment&#xff08;1&#xff09;确认需求&#xff08;2&#xff09;创建 <1> 方法一&#xff1a;借助工具快速生成 <2> 方法二&#xff1a;视图&#xff08;图层&#xff09;工具 <3> 方法三&#xff1a;手动…

知网G4《语数外学习》简介及投稿邮箱

知网G4教育专刊《语数外学习》简介及投稿邮箱 《语数外学习》全新改版&#xff0c;分别针对初中三个不同年级&#xff0c;每本仍然兼顾语数外三个学科。改版后的《语数外学习》将密切关注课改和中考改革的进程&#xff0c;与教材同步&#xff0c;在帮中学生朋友释疑疑惑、提高…

DOTA-PEG3-azide,1428146-79-5,DOTA三聚乙二醇叠氮,试剂相关研究说明

DOTA-PEG3-azide&#xff0c;DOTA PEG3 N3&#xff0c;DOTA三聚乙二醇叠氮产品结构式&#xff1a; 产品规格&#xff1a; 1.CAS号&#xff1a;1428146-79-5 2.分子式&#xff1a;C24H44N8O10 3.分子量&#xff1a;604.66 4.包装规格&#xff1a;白色固体 &#xff0c;1g、5g、1…

数据库性能测试

目录 前言&#xff1a; 1.引入数据库驱动包 2.添加数据库配置元件 3、JDBCRequest参数化 4、Variablesnames参数使用方法&#xff1a; 前言&#xff1a; 数据库性能测试是测试数据库系统在各种条件下的性能和稳定性的过程。它可以帮助测试人员识别数据库系统的性能瓶颈&a…

30余名「实在RPA·数字员工」在纳爱斯诞生,在618中服务千万消费者!

积水成渊&#xff0c;聚沙成塔&#xff01;谁在世界数字化大势中不断变革自己&#xff1f; 长期蝉联“中国品牌价值评价”日化行业首位&#xff0c;问鼎中国工业“奥斯卡”大奖的“大国品牌”纳爱斯——当仁不让&#xff01; 纳爱斯是日化行业领军企业&#xff0c;业务覆盖家…

SpringBoot整合MybatisPlus 自动生成controller、mapper、entity、service

首先创建SpringBoot项目 选择依赖 把application的后缀改为.yml&#xff0c;方便些。 pom.xml&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w…

一次完整的性能测试,测试人员需要做什么

目录 前言&#xff1a; 一、 规范性能测试实施流程的意义 二、 性能测试实施流程 1. 需求调研阶段 2. 测试准备阶段 3. 测试执行阶段 4. 测试报告阶段 5. 测试总结阶段 前言&#xff1a; 进行一次完整的性能测试需要经过多个阶段&#xff0c;包括需求分析、测试计划编…

OpenStack(3)--vxlan网络实战

目录 一、ML2配置文件 二、上传cirros镜像 三、创建vxlan10网络 四、创建实例/同vxlan通信测试 五、不同vxlan通信测试 5.1 新建vxlan11 5.2 新建路由/添加路由接口 5.3 不同vxlan通信测试 5.4 qemu-vnc报错 六、深度剖析vxlan 七、认识 Bridge br-ex、Bridge br-in…

「一本通 3.2 练习 6」汽车加油行驶

目录 第一步&#xff0c;二维转一维&#xff08;此步仅为方便&#xff0c;可以省略&#xff09; 第二步&#xff0c;建边&#xff08;啥都行&#xff0c;只要死不了&#xff09; 第三部&#xff0c;bfs&#xff08;你要dfs也行&#xff09; 第一步 第二步 第三步 可CA呢…

蓝桥杯专题-试题版-【01字符串】【2n皇后问题】【A+B问题】【Fibonacci数列】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

ECS 简略版说明一:Entities and components

目录 Entities and components Worlds and EntityManagers Archetypes Chunks Queries Entity IDs IComponentData Managed IComponentData components DynamicBuffer components Aspects Allocator overview Allocator.Temp Allocator.TempJob Allocator.Persis…

MySQL性能测试及调优中的死锁处理方法

目录 前言&#xff1a; 1、死锁检测 2、死锁避免 3、死锁解决 前言&#xff1a; MySQL死锁是指多个会话同时请求相同资源时发生的一种资源争用现象&#xff0c;导致会话无法继续执行。死锁的发生会导致事务无法提交或者回滚&#xff0c;影响应用程序的正常运行。因此&#xff0…