数据结构——队列(C语言版)

前言:

在学习完数据结构顺序表和链表之后,其实我们就可以做很多事情了,后面的栈和队列,其实就是对前面的顺序表和链表的灵活运用,今天我们就来学习一下队列的原理和应用。

准备工作:本人习惯将文件放在test.c、SeqList.c、SeqList.h三个文件中来实现,其中test.c用来放主函数,SeqList.c用来放调用的函数,SeqList.h用来放头文件和函数声明

目录

什么是队列?

队列的节点结构

队列的基本操作

1、初始化

2、销毁

3、增加(插入数据)

4、删除

5、取队头、取队尾、取长度、判断头指针是否为空

完整的队列实例

总结


什么是队列?

队列中的数据是按照先进先出的顺序的,也就是说先进去的数字也先出来

因为队列的这种性质,所以队列我们用链表来实现比顺序表方便很多,因为用顺序表每插入一个数或者删除一个数都需要遍历整个数组,这样就会很容易出错且不够方便,我们一般采用单链表来实现队列

队列的节点结构

队列采用的单链表的结构,所以与单链表差异不大

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

但是我们在操作中,因为队列是要先进先出,其实也就是尾部进数据,头部出数据,所以我们要定义一个头指针和一个尾指针指向头尾两个数据,这样有利于我们后面增加或者删除数据,我们可以再定义一个结构体来存放这两个指针

typedef struct Queue
{QNode* phead;    //头指针QNode* ptail;    //尾指针int size;        //队列中的元素个数
}Queue;

队列的基本操作

//初始化
void QueueInit(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
//增加
void QueuePush(Queue* pq,QDataType x);
//删除
void QueuePop(Queue* pq);
//取队头
QDataType QueueFront(Queue* pq);
//取队尾
QDataType QueueBack(Queue* pq);
//取长度
QDataType QueueSize(Queue* pq);
//判断是否为空
bool QueueEmpty(Queue* pq);

看上面的函数声明部分我们就可以看到我们每一步要实现的内容,接下来,我们就来一步一步进行实现

1、初始化

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

参数全是一个结构体指针,而且肯定不能为空,所以我们下面的函数基本都要对pq进行断言

2、销毁

将头指针指向的空间逐个释放,最后把头指针和尾指针均赋为空指

//销毁
void QueueDestroy(Queue* pq)
{QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}

3、增加(插入数据)

因为先进先出,实际上数据就是从尾部插入,从头部出去,即插入形式为尾插

//插入
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));newnode->data = x;newnode->next = NULL;//判断头部是否为空if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}

用单链表插入数据必须要考虑头部为空和不为空两种情况

4、删除

栈和队列都有一个特点就是,数据只会输出一遍,也就是数据一经输出就会销毁删除

如下:

1在输出之后就会被删除,删除的代码如下:

//删除
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));//1、一个节点//2、多个节点if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* ptr = pq->phead->next;free(pq->phead);pq->phead = ptr;}
}

这里面又分为两种情况,难度不大,根据注释自行体会即可

5、取队头、取队尾、取长度、判断头指针是否为空

这几步难度不大,放在一起看看

取队头

//取队头
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}

取队尾

//取队尾
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}

取长度

//取长度
QDataType QueueSize(Queue* pq)
{assert(pq);return pq->size;
}

判断头指针是否为空(这个函数应用上可以在下面的完整案列上体会一下)

bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}

完整的队列实例

test.c

//队列
void TestQNode()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);printf("%d\n", QueueSize(&q));while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueueDestroy(&q);
}
int main()
{TestQNode();return 0;
}

SeqList.h

//队列
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;//初始化
void QueueInit(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
//增加
void QueuePush(Queue* pq,QDataType x);
//删除
void QueuePop(Queue* pq);
//取队头
QDataType QueueFront(Queue* pq);
//取队尾
QDataType QueueBack(Queue* pq);
//取长度
QDataType QueueSize(Queue* pq);
//判断是否为空
bool QueueEmpty(Queue* pq);

SeqList.c

//初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
//销毁
void QueueDestroy(Queue* pq)
{QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
//插入
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));newnode->data = x;newnode->next = NULL;if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
//删除
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));//1、一个节点//2、多个节点if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* ptr = pq->phead->next;free(pq->phead);pq->phead = ptr;}
}
//取队头
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}
//取队尾
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}
//取长度
QDataType QueueSize(Queue* pq)
{assert(pq);return pq->size;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}

运行后结果:

总结

总之,其实队列就是对链表的应用,熟练栈和队列,对我们巩固顺序表和链表帮助很大,当然,队列在一些场景下很实用,后面我会出一个专门的习题讲解篇章,讲数据结构的一些经典题型,感兴趣的可以点赞关注一下

创作不易,还请各位大佬点赞支持一下!!!

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

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

相关文章

美国大选献金项目数据分析

需求 加载数据查看数据的基本信息指定数据截取,将如下字段的数据进行提取,其他数据舍弃 cand_nm :候选人姓名contbr_nm : 捐赠人姓名contbr_st :捐赠人所在州contbr_employer : 捐赠人所在公司contbr_occu…

搭建Flutter开发环境、从零基础到精通(文末送书【北大出版社】)

目录 搭建开发环境 1. 下载Flutter SDK 2. 设置镜像地址及环境变量 3. 安装与设置Android Studio 4. 安装Visual Studio Code与Flutter开发插件 5. IDE的使用和配置 6. 安装Xcode 7. 检查Flutter开发环境 好书推荐 内容简介 作者简介 搭建开发环境 Flutter可以跨平…

selenium完结篇,补充知识点

1、前两期没看的建议先去看前两期博客 2、选择框的勾选 getAttribute("type")是获取属性的意思 List<WebElement> webElementswebDriver.findElements(By.cssSelector("input"));for(int i0;i<webElements.size();i){if(webElements.get(i).getA…

使用npm i进行admin依赖安装的时候出现问题

提示&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/string-width failed, reason: certificate has expired 切换淘宝源到http或者更换其他国内镜像 npm config set registry http:/…

Salesforce宣布将停用Workflow Rules和Process Builder!

在近期的公告中&#xff0c;Salesforce透露在2025年12月31日之后将不再支持Workflow Rules和Process Builder。 Salesforce敦促用户在截止日期前将其自动化流程迁移到Flow Builder&#xff0c;以确保不间断的支持和漏洞修复。此举正值Salesforce将重点转向更现代、可扩展、低代…

rust中常用cfg属性和cfg!宏的使用说明,实现不同系统的条件编译

cfg有两种使用方式&#xff0c;一种是属性&#xff1a; #[cfg()]&#xff0c;一种是宏&#xff1a;cfg! &#xff0c;这两个都是非常常用的功能。 #[cfg()]是 Rust 中的一个属性 用于根据配置条件来选择性地包含或排除代码。cfg 是 "configuration" 的缩写&#xf…

Web举例:防火墙二层,上下行连接交换机的主备备份组网

Web举例&#xff1a;防火墙二层&#xff0c;上下行连接交换机的主备备份组网 介绍了业务接口工作在二层&#xff0c;上下行连接交换机的主备备份组网的Web举例。 组网需求 如图1所示&#xff0c;两台FW的业务接口都工作在二层&#xff0c;上下行分别连接交换机。FW的上下行业…

中小型集群部署,Docker Swarm(集群)使用及部署应用介绍

1、Docker Swarm简介 说到集群&#xff0c;第一个想到的就是k8s&#xff0c;但docker官方也提供了集群和编排解决方案&#xff0c;它允许你将多个 Docker 主机连接在一起&#xff0c;形成一个“群集”&#xff08;Swarm&#xff09;&#xff0c;并可以在这个 Swarm 上运行和管…

Go语言学习Day4:函数(上)

名人说&#xff1a;莫愁千里路&#xff0c;自有到来风。 ——钱珝 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、函数的概念与定义①函数的概念②函数的具体定义③多返回值 2、函数参数与作用域①可变参数②形…

【零基础C语言】文件操作

目录 理解文件操作 什么是文件 程序文件 数据文件 文件名字 二进制文件和文本文件 文件的打开和关闭 文件的打开和关闭操作 实验1&#xff0c;打开一个文件并且输入26个字母 打开读取文件text.txt ,并且将它拷贝进text_cpy.txt 使用 fputs 和 fgets 函数 使用 fprintf函…

【计算机网络】IP 协议

网络层IP协议 一、认识 IP 地址二、IP 协议报头格式三、网段划分1. 初识子网划分2. 理解子网划分3. 子网掩码4. 特殊的 IP 地址5. IP 地址的数量限制6. 私有 IP 地址和公网 IP 地址7. 理解全球网络&#xff08;1&#xff09;理解公网&#xff08;2&#xff09;理解私网&#xf…

华为汽车图谱

极狐 极狐&#xff08;ARCFOX&#xff09;是由北汽、华为、戴姆勒、麦格纳等联合打造。总部位于北京蓝谷。 问界 华为与赛力斯&#xff08;东风小康&#xff09;合作的成果。 阿维塔 阿维塔&#xff08;AVATR&#xff09;是由长安汽车、华为、宁德时代三方联合打造。公司总部位…

canal: 连接kafka (docker)

一、确保mysql binlog开启并使用ROW作为日志格式 docker 启动mysql 5.7配置文件 my.cnf [mysqld] log-binmysql-bin # 开启 binlog binlog-formatROW # 选择 ROW 模式 server-id1一定要确保上述两个值一个为ROW&#xff0c;一个为ON 二、下载canal的run.sh https://github.c…

一周学会Django5 Python Web开发-Django5模型定义

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计41条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

26. BI - PageRank 拓展以及如何利用 networkx 来分析希拉里丑闻

本文为 「茶桁的 AI 秘籍 - BI 篇 第 26 篇」 Hi, 我是茶桁. 上节课咱们讲解了 PageRank 的两种模型, 并分别做了代码上的演示. 这节课, 让我们来看看 PageRank 的影响力及其应用. PageRank 已经超越了原来提出来的模型, 因为 PageRank 的影响力影响到了后续很多的一些模型, …

我的创作纪念日 ---- 2024/3/26

前言 2024.3.26是我在CSDN成为创作者的第128天&#xff0c;也是我第一次真正在网上创作的第128天 当我还在日常创作时&#xff0c;突然发现我收到了一封信 我想我可以分享一下这段时间的感想以及收获 机缘 在CSDN的这段时间里&#xff0c;我学习到了很多知识&#xff0c;也…

数据结构——链表(单链表)

大家好&#xff0c;又是我&#xff08;小锋&#xff09;&#xff0c;今天给大家带了一个比较有挑战的章节&#xff08;链表&#xff09;&#xff0c;但是不用担心&#xff0c;小锋会陪大家一起度过。 顺序表的思考与问题 1. 中间/头部的插入删除&#xff0c;时间复杂度为O(N) …

【python】flask模板渲染引擎Jinja2,通过后端数据渲染前端页面

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Spring Cloud 八:微服务架构中的数据管理

Spring Cloud 一&#xff1a;Spring Cloud 简介 Spring Cloud 二&#xff1a;核心组件解析 Spring Cloud 三&#xff1a;API网关深入探索与实战应用 Spring Cloud 四&#xff1a;微服务治理与安全 Spring Cloud 五&#xff1a;Spring Cloud与持续集成/持续部署&#xff08;CI/C…

Eladmin-jpa基于SpringBoot和Vue的前后端分离后台管理系统​

在当今快速发展的软件开发领域&#xff0c;前后端分离的架构模式已经成为主流。这种架构模式不仅可以提高开发效率&#xff0c;还能使系统更加易于维护和扩展。Eladmin-jpa是一个基于Spring Boot 2.6.4、Spring Boot Jpa、JWT、Spring Security、Redis和Vue的前后端分离的后台管…