【数据结构】队列详解

Hello everybody!今天给大家讲讲队列的相关知识。队列,属于一种数据结构。从字面意思上理解,就像是排队一样,在食堂中,先排队的人自然就先买到饭。队列也是如此,先入队列的数据自然就先出队列。希望大家可以通过这篇文章解决自己心中的疑惑!那废话不多说,让我们开始叭!

                ​​​​​​​        ​​​​​​​      

1.队列的概念及结构

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

入队列:进行插入操作的一端称为队尾

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

2.队列的实现

队列可以以数组和链表的结构实现,使用链表的结构实现更优,因为如果使用数组的结构,出队列是需要移动数据,时间复杂度是O(n),效率比较低。

由于实现队列需要较长的代码,因此我们要像公司中做大型项目一样创建一个头文件:Queue.h和两个源文件:Queue.c Test.c。

头文件中需要包含所需要的库文件,接口的声明,队列的声明。总之就是要我们清晰的看到队列的结构和功能。

而源文件Queue.c需要实现在头文件中声明的接口。

源文件Test.c用于测试队列的功能是否正常。

当然源文件需要包含头文件,这样才能把它们关联起来。

创建三个文件使得代码逻辑更加清晰,有利于后期代码的维护。

2.1接口的声明&队列的声明

这是队列的结构,结构体QNode是队列的链式结构,它可以存放当前结点的值和下一个结点的地址。但是当队列为空,插入第一个数据时,需要改变头指针。因此需要传递二级指针,这样显然是有些麻烦的。所以我们再创建一个结构体Queue,用于存放队列的头指针和尾指针,更方便入队和出队。size用来记录队列中的元素个数。

以上是队列主要功能的接口,下面我们来逐个实现它们。

2.2接口的实现及功能测试

目前为止,我们已经实现了初始化和入队两个接口。下面测试一下它们的功能。

通过调试,我们可以看到:初始化后,在队尾成功插入1和2。目前队列中有两个数值,接口功能正常。

下面我们来实现一下其他的接口:

这是队列剩下的接口,咱们也来测试一下。

从测试结果来看:各个接口功能正常,销毁队列后,头指针和尾指针都被置为空指针,队列大小size为0。符合要求。

3.代码

为了方便大家更好的学习,队列的代码我也给出来!

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int  QDataType;
typedef struct QueueNode {QDataType val;struct QueueNode* next;
}QNode;
typedef struct Queue {QNode* phead;QNode* ptail;int size;
}Queue;void QueueInit(Queue* pq);//初始化
void QueuePush(Queue* pq, QDataType x);//入队
void QueuePop(Queue* pq);//出队
void QueueDestroy(Queue* pq);//销毁
QDataType QueueFront(Queue* pq);//返回队头的值
QDataType QueueBack(Queue* pq);//返回队尾的值
bool QueueEmpty(Queue* pq);//判断队列是否为空
int QueueSize(Queue* pq);//返回队列的数据个数
#include "Queue.h"
void QueueInit(Queue* pq) {assert(pq);//检验pq是否为空指针pq->phead = pq->ptail = NULL;pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x) {assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));//动态开辟一个新结点if (newnode == NULL) {//若开辟失败,终止程序perror("malloc fail");exit(-1);}newnode->val = 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(pq->phead);//队列不能为空QNode* next = pq->phead->next;//记录头结点的下一个结点free(pq->phead);pq->phead = next;if (pq->phead == NULL) {//当phead为NULL时,ptail没有变化。但ptail指向的空间已经还给操作系统,此时ptail就是野指针,必须处理掉!pq->ptail = NULL;}pq->size--;
}
QDataType QueueFront(Queue* pq) {assert(pq);assert(pq->phead);return pq->phead->val;
}
QDataType QueueBack(Queue* pq) {assert(pq);assert(pq->ptail);return pq->ptail->val;
}
bool QueueEmpty(Queue* pq) {assert(pq);return pq->phead == NULL;
}
int QueueSize(Queue* pq) {assert(pq);return pq->size;
}
void QueueDestroy(Queue* pq) {assert(pq);while (pq->phead) {QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
#include "Queue.h"
int main() {Queue pq;QueueInit(&pq);QueuePush(&pq, 1);QueuePush(&pq, 2);QueuePush(&pq, 3);QueuePush(&pq, 4);printf("%d\n", QueueBack(&pq));printf("%d\n", QueueSize(&pq));while (!QueueEmpty(&pq)) {printf("%d", QueueFront(&pq));QueuePop(&pq);}QueueDestroy(&pq);return 0;
}

4.结语

好啦,关于队列的讨论就到这里叭。不知道大家有没有收获呢?如果有疑问,可以发在评论区。

最后,希望宝子们每天都有所进步,成为自己想成为的人,做自己想做的事!\(0^◇^0)/

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

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

相关文章

C语言生成dll与lib文件

环境要求 新建一个空白项目&#xff0c;可以是exe的&#xff0c;也可以直接是dll的&#xff0c;也可以是啥都没有的空项目&#xff0c;推荐创建空项目&#xff0c;项目创建好以后进行配置&#xff0c;共两步 第一步&#xff0c;打开项目属性 第二步&#xff0c;设置配置类型…

使用Python处理ADC激光测距数据并绘制为图片(二)

使用Python处理ADC激光测距数据并绘制为图片 说明一、定义全局变量变二、保存和清空原始数据三、拆分原始数据为键值对四、获取标题、FigText、更新统计信息文件五、生成图片六、处理原始数据文件七、主函数入口八、测试结果 说明 1. 主要是将ADC激光测距叠加后的1024Byte数据绘…

哪个才是最适合你的 Web UI 自动化测试框架

最近&#xff0c;项目上出于系统性稳定性、减少测试工作量考虑&#xff0c;打算在 Web 前端引入 BDD。由于上一个项目写了一定的 Cucumber 代码&#xff08;BDD 测试框架之一&#xff09;&#xff0c;这个框架选型的责任便落到了我的肩膀上了。 在我们进行框架选型的时候&#…

字符数组基础知识

字符数组是存放字符数据的数组&#xff0c;其中每一个元素存放的值都是单个字符。 字符数组&#xff1a;由字符类型的元素组成&#xff0c;其定义与初始化方式&#xff0c;以及对数组元素的引用都与整数数组类似&#xff0c;代码示例 char c[5]{h,e,l,l,,o}; 注意&#xff1…

debian 修改IP 重启网络

vi /etc/network/interfaces /etc/init.d/networking restart

【SA8295P 源码分析 (三)】132 - GMSL2 协议分析 之 GPIO/SPI/I2C/UART 等通迅控制协议带宽消耗计算

【SA8295P 源码分析】132 - GMSL2 协议分析 之 GPIO/SPI/I2C/UART 等通迅控制协议带宽消耗计算 一、GPIO 透传带宽消耗计算二、SPI 通迅带宽消耗计算三、I2C 通迅带宽消耗计算四、UART 通迅带宽消耗计算系列文章汇总见:《【SA8295P 源码分析 (三)】Camera 模块 文章链接汇总 -…

如何做好前端单元测试?字节5年测试老司机是这样说的!

近几年&#xff0c;前端发展越来越迅猛&#xff0c;各类框架层出不穷&#xff0c;前端实现的业务逻辑也越来越复杂&#xff0c;前端单元测试也越来越受重视&#xff0c;包括百度在内的一些大厂在面试中也会问到单元测试相关的题目。那么前端应该如何做好单元测试&#xff1f; 什…

安全知识普及:了解端点检测与响应 (EDR)对企业的重要性

文章目录 EDR 的含义和定义EDR 是如何运作的&#xff1f;收集端点数据将数据发送到 EDR 平台分析数据标记可疑活动并做出响应保留数据以供日后使用 为什么 EDR 对企业至关重要大多数企业都有可能遭受各种网络攻击。有些攻击可以完全绕开企业的防御远程办公让员工缺乏足够的保护…

杨氏矩阵解法

每日一言 「 人生如逆旅&#xff0c;我亦是行人。 」--临江仙送钱穆父-苏轼题目 杨氏矩阵 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 解法思路 法一&#xff1a;…

三字经||无聊数了下三字经的字数

三字经总字数去除标点后1416个 该文章无技术含量&#xff0c;仅三字经原文&#xff0c;学技术的同学可以止步了 三字经&#xff08;原文&#xff09; 【作者】王应麟 【朝代】南宋 人之初&#xff0c;性本善。性相近&#xff0c;习相远。 苟不教&#xff0c;性乃迁。教之道&a…

【SpringBoot】Redission 的使用与介绍

背景&#xff1a; 我想我们用到 Redisson 最多的场景一定是分布式锁&#xff0c;一个基础的分布式锁具有三个特性&#xff1a; 互斥&#xff1a;在分布式高并发的条件下&#xff0c;需要保证&#xff0c;同一时刻只有有一个线程获得锁&#xff0c;这是最基本的一点。 防止死…

基于知识问答的上下文学习中的代码风格11.20

基于知识问答的上下文学习中的代码风格 摘要1 引言2 相关工作3 方法3.1 概述3.2 元函数设计3.3 推理 4 实验4.1 实验设置4.2 实施细节4.3 主要结果 摘要 现有的基于知识的问题分类方法通常依赖于复杂的训练技术和模型框架&#xff0c;在实际应用中存在诸多局限性。最近&#x…

泵类设备常见的5种故障及监测方法

在各种工业领域中&#xff0c;泵是一种关键设备&#xff0c;用于输送液体或气体。然而&#xff0c;泵类设备常常会面临各种故障&#xff0c;这可能导致生产停顿和生产效率下降。为了及时监测并解决这些故障&#xff0c;设备状态监测系统成为一种重要的工具。本文将介绍泵类设备…

静态工具类中注入Bean及引用Nacos配置

目录 1.说明 2.示例 1.说明 在代码开发中&#xff0c;经常会存在调用第三方工具或者其他系统的场景&#xff0c;通常封装成一个工具类供service进行调用&#xff0c;便于后期的维护及代码复用。工具类中的属性及方法都被static修饰&#xff0c;在工具类中不能使用和service中…

Pytorch torch.norm函数详解用法

torch.norm参数定义 torch版本1.6 def norm(input, p"fro", dimNone, keepdimFalse, outNone, dtypeNone)input input (Tensor): the input tensor 输入为tensorp p (int, float, inf, -inf, fro, nuc, optional): the order of norm. Default: froThe following …

零代码编程:用ChatGPT将SRT字幕文件批量转为Word文本文档

一个文件夹中有多个srt视频字幕文件&#xff0c;srt文件里面有很多时间轴&#xff1a; 现在想将其批量转为word文档&#xff0c;去掉里面与字符无关的时间轴&#xff0c;在ChatGPT中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个批量将SRT字幕文件转为…

js 数组中使用 push 报错

文章目录 问题分析 问题 代码如下&#xff0c;但报错如上&#xff0c;请分析上述代码错误原因 let arr [[160, 20], [179, 10], [-170, -20]]; let temp arr.unshift([1,1]); let tt temp.push([0,0])console.log(tt); // 输出新生成的数组分析 这段代码有几个错误&#x…

opencv-形态学处理

通过阈值化分割可以得到二值图&#xff0c;但往往会出现图像中物体形态不完整&#xff0c;变的残缺&#xff0c;可以通过形态学处理&#xff0c;使其变得丰满&#xff0c;或者去除掉多余的像素。常用的形态学处理算法包括&#xff1a;腐蚀&#xff0c;膨胀&#xff0c;开运算&a…

CDN加速在目前网络安全里的重要性

在当今数字化时代&#xff0c;网络已经成为我们生活不可或缺的一部分。然而&#xff0c;随之而来的是网络安全的威胁不断增加&#xff0c;为了应对这一挑战&#xff0c;CDN&#xff08;内容分发网络&#xff09;的应用变得愈发重要。本文将从一个旁观者的角度分析当前的网络安全…