【数据结构】 队列详解!庖丁解牛般细致讲解!

news2024/12/24 20:45:01

在这里插入图片描述

🎥 屿小夏 : 个人主页
🔥个人专栏 : 数据结构解析
🌄 莫道桑榆晚,为霞尚满天!

文章目录

  • 📑前言
  • 🌤️队列的概念剖析
    • ☁️什么是队列
    • ☁️队列的特性
    • ☁️队列的图解
  • 🌤️队列的详细实现
    • ☁️队列不同的实现方式
    • ☁️队列结构体
    • ☁️队列的初始化
    • ☁️入队列
    • ☁️出队列
    • ☁️获取对头元素
    • ☁️获取队尾元素
    • ☁️队列的判空
    • ☁️队列有效的元素个数
    • ☁️队列的销毁
  • 🌤️队列的应用场景
  • 🌤️全篇总结

📑前言

什么是队列?队列有什么样的特性?它的应用场景有哪些?
本文会对队列这种数据结构进行进行庖丁解牛般的讲解,让你彻底学会数据结构!

🌤️队列的概念剖析

☁️什么是队列

队列是一种常见的数据结构,它按照先进先出(FIFO)的原则进行操作。队列中的元素按照进入的顺序排列,新元素插入到队列的一端,称为队尾,已有元素的删除操作则发生在队列的另一端,称为队头。

☁️队列的特性

  1. 先进先出(FIFO):队列中的元素按照进入的顺序排列,最先进入的元素最先被删除。
  2. 只能在队尾插入元素:新元素只能从队尾插入。
  3. 只能在队头删除元素:已有元素只能从队头删除。
  4. 队列长度可变:队列的长度可以根据需要动态变化。
  5. 队列可以为空:队列中没有元素时为空队列。
  6. 队列可以为满:队列中的元素数量达到了队列的最大容量时为满队列。

☁️队列的图解

在这里插入图片描述

这个可以简单理解成,就像是我们生活中的食堂打饭排队一样,先来的在前面后来的在后面,前面的打完饭后就走了。这就像是数据结构中的队列。

🌤️队列的详细实现

☁️队列不同的实现方式

  1. 数组实现:使用数组来存储队列中的元素,通过两个指针分别指向队头和队尾。入队操作时,将新元素插入到队尾,同时移动队尾指针;出队操作时,删除队头元素,同时移动队头指针。这种实现方式简单直观,但在动态扩容时需要进行数据的搬移,效率较低。
  2. 链表实现:使用链表来存储队列中的元素,每个节点包含一个元素和一个指向下一个节点的指针。入队操作时,创建一个新节点并插入到链表的末尾;出队操作时,删除链表的头节点。这种实现方式不需要进行数据的搬移,但需要额外的空间来存储指针。

本文我们的队列使用链表的形式来进行队列的实现。这里更推荐链表实现起来不会那么复杂。

在这里插入图片描述

☁️队列结构体

typedef int QDatatype;
 
typedef struct Qlistnode
{
	struct Qlistnode* next;
	QDatatype data;
}Qlistnode;
 
typedef struct Queue
{
	Qlistnode* fornt;
	Qlistnode* rear;
	int size;
}Queue;

对数据类型进行重命名,这样以后需要更换其他数据类型使用的时候只需要更改这一个地方就可以了。

​ 这里有两个结构体,进行了嵌套。定义一个链表的结点,包含当前结点元素和指向下一个结点的指针。然后定义一个队列结构体,队列中两个结构体体指针分别代表队头和队尾,size是当前队列的有效元素个数。

​ 这样做的目的是,方便了队列的头删(出队列)和尾插(入队列),已经获取队列内的元素个数和队尾、队头的元素。

☁️队列的初始化

void QueueInit(Queue* q)
{
	assert(q);
	q->fornt = NULL;
	q->rear = NULL;
	q->size = 0;
}

这里先将所以的指针都置空,size为0,因为是初始化所以队中无元素。

☁️入队列

在队列插入数据,要先开辟一个结点的空间,用来存放值和下一个结点的地址。这里要进行两种情况的判断:如果队头为空时,代表此时队列中无元素,那么队头和队尾指针指向同一块空间。当队头不为空时,就将队尾的指针指向新开辟的结点。插入新数据后,size的个数++。

在这里插入图片描述

void QueuePush(Queue* q, QDatatype x)
{
	assert(q);
 
	Qlistnode* newnode = (Qlistnode*)malloc(sizeof(Qlistnode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (q->rear == NULL)
	{
		q->fornt = q->rear = newnode;
	}
	else
	{
		q->rear->next = newnode;
		q->rear = newnode;
	}
	q->size++;
}

☁️出队列

在队头删除数据,此处和入队列一样,要进行两种情况的判断:

​ 如果队头和队尾指针同时指向一块空间时,此时队列中只有一个元素,所以释放队头或队尾指针都可,然后将队头和队尾指针置空,方便下一次进行插入数据(入队列)。

​ 队头和队尾指针不相等时,表名队列有最少一个以上的元素,创建一个临时结点用来存放队头指针下一个元素的地址,然后释放队头指针,再让队头指针指向下一个元素。

​ 出队列后,队列中的有效元素个数就少了一个,所以size也要进行–。

在这里插入图片描述

void QueuePop(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
 
	if (q->fornt == q->rear)
	{
		free(q->fornt);
		q->fornt = NULL;
		q->rear = NULL;
	}
	else
	{
		Qlistnode* newnode = q->fornt->next;
		free(q->fornt);
		q->fornt = newnode;
	}
	q->size--;
}

☁️获取对头元素

要获取元素前需要进行判空,如果队列是空,那么就会报错。

队头指针指向的就是队列的首元素地址,进行解引用就可以获取队头的元素。

QDatatype QueueFornt(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
 
	return q->fornt->data;
}

☁️获取队尾元素

要获取元素前需要进行判空,如果队列是空,那么就会报错。

队头指针指向的就是队尾的首元素地址,进行解引用就可以获取队尾的元素。

QDatatype QueueRear(Queue* q)
{
	assert(q);
	assert(!QueueEmpty(q));
 
	return q->rear->data;
}

☁️队列的判空

队列如果为空的情况下代表队头指针是空,此时队列无元素。

bool QueueEmpty(Queue* q)
{
	assert(q);
 
	return q->fornt ==  NULL;
}

☁️队列有效的元素个数

我们先前定义的size就是队列中有效元素的个数。

int QueueSize(Queue* q)
{
	assert(q);
	
	return q->size;
}

☁️队列的销毁

因为队列是链表实现的,所以这里的释放空间要写成循环,释放队列中每一个结点的空间。

创建临时指针,让newnode去迭代。最后队头和队尾指针都置空,size归0。

void QueueDestroy(Queue* q)
{
	assert(q);
 
	Qlistnode* newnode = q->fornt;
	while (newnode)
	{
		q->fornt = newnode->next;
		free(newnode);
		newnode = q->fornt;
	}
	q->fornt = q->rear = NULL;
	q->size = 0;
}

🌤️队列的应用场景

队列在计算机科学和软件开发中有广泛的应用场景:

  1. 任务调度:队列可以用来实现任务调度系统,将待执行的任务按照先后顺序排列,每次从队头取出一个任务进行执行,保证任务按照顺序执行。
  2. 消息传递:队列可以用来实现消息传递系统,消息发送方将消息入队,消息接收方从队头出队获取消息。这种方式可以实现异步消息传递,并且可以处理消息的积压情况。
  3. 缓冲区:队列可以用来实现缓冲区,例如网络数据传输中的数据包缓冲区、磁盘读写中的数据缓冲区等。数据可以按照顺序入队,然后按照顺序出队进行处理,保证数据的有序性和流畅性。
  4. 广度优先搜索:在图的广度优先搜索算法中,使用队列来存储待访问的节点,每次从队头取出一个节点进行访问,并将其邻接节点入队。这样可以保证按照层次遍历图的节点,从而实现广度优先搜索。
  5. 线程池:在多线程编程中,线程池可以使用队列来实现任务的调度。将待执行的任务入队,线程池中的线程从队头取出任务进行执行,保证任务的有序执行和线程的复用。

以上只是一些常见的应用场景,队列还可以用于解决其他问题,如数据流量控制、请求排队、打印队列等。队列的先进先出特性使其在这些场景下能够提供高效的数据处理和调度能力。

🌤️全篇总结

本篇对队列这种数据结构进行了概念的说明,对队列的实现细致入微,最后普及了队列这种数据结构的泛用性!

☁️ 好啦,由于篇幅有限,本章仅对队列进行了细致入微的讲解,后序还会有更多的数据结构文章分享哦!
看到这里了希望给博主留个:👍 点赞🌟收藏 ⭐️ 关注!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
在这里插入图片描述

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

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

相关文章

【鸿蒙软件开发】ArkTS容器组件之Badge

文章目录 前言一、Badge组件1.1 子组件1.2 接口接口1参数 接口2参数 BadgePosition枚举说明BadgeStyle对象说明 1.3 示例代码 总结 前言 Badge组件:可以附加在单个组件上用于信息标记的容器组件。 一、Badge组件 可以附加在单个组件上用于信息标记的容器组件。 说…

光强的检测与控制系统设计

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、实习内容二、实习方法2.1 proteus仿真部分2.2 使用Altium designer软件绘制原理图2.2.1 工程创建2.2.2 绘制封装以及链接封装与原件原理图2.2.3检查原件原理…

python不同版本的下载安装和配置

python下载和安装 1 基础软件安装 sudo apt update sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget2 python压缩文件下载 我这里下载的是3.9.9,各位也可以根据自己需要下…

精品Python的定制化图书借阅推荐引擎设计与实现

《[含文档PPT源码等]精品基于Python的定制化图书推荐引擎设计与实现》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功! 软件开发环境及开发工具: 开发语言:python 使用框架:Django 前端技…

【机器学习】loss损失讨论

大纲 验证集loss上升,准确率也上升(即将overfitting?)训练集loss一定为要为0吗 Q1. 验证集loss上升,准确率也上升 随着置信度的增加,一小部分点的预测结果是错误的(log lik 给出了指数级的惩…

VSCode编写Unity代码自动补全配置

1.下载并安装.NET 7.0(C#插件需要)和.NET Framework 4.7.1(Unity需要) .NET 7.0下载链接:https://dotnet.microsoft.com/en-us/download .NET Framework 4.7.1下载链接:https://dotnet.microsoft.com/en-…

Python 日期和时间处理教程:datetime 模块的使用

Python 中的日期不是独立的数据类型,但我们可以导入一个名为 datetime 的模块来使用日期作为日期对象。 示例:导入 datetime 模块并显示当前日期: import datetimex datetime.datetime.now() print(x)日期输出 当我们执行上面示例中的代码…

Java利用Scanner类,从键盘接受一个字符串输入,该字符串包含小写字母,大写字母和数字。分别输出该字符串所包含的大写字母、小写字母和数字的个数。

题目要求:利用Scanner类,从键盘接受一个字符串输入,该字符串包含小写字母,大写字母和数字。分别输出该字符串所包含的大写字母、小写字母和数字的个数。 import java.util.Scanner;public class Demo1 {public static void main(…

算法篇 : 并查集

介绍 英文名:union find set 作用:合并集合,查询集合 合并:将有直接关系的顶点放在一个集合里面 查找:查询某个顶点所属的集合 集合的标志:用祖先点的标号作为每个集合的标识 案例 如果说将下图的集合2合并…

H5游戏源码分享-接苹果游戏拼手速

H5游戏源码分享-接苹果游戏拼手速 看看在20秒内能接多少个苹果 <html> <head><title>我是你的小苹果</title><meta charset"utf-8"/><meta name"viewport" content"initial-scale1, user-scalableno, minimum-scale…

【DevChat】智能编程助手 - 使用评测

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

【unity小技巧】unity排序问题的探究

文章目录 前言一、排序图层二、sorting Group的使用三、树木排序设计方法一 代码控制方法二 拆分图片方法三 透视排序1. 普通物品排序2. TileMap瓦片排序设计 完结 前言 unity的排序问题其实之前分享的项目多多少少都有提到一点&#xff0c;但是没有单独拿出来说&#xff0c;所…

常用第三方库

Moment GTC(Greenwish Mean Time)&#xff1a;格林威治时间&#xff0c;太阳时&#xff0c;精确到毫秒UTC(Universal Time Coodinated)&#xff1a;世界协调时间&#xff0c;原子种计时&#xff0c;精确到纳秒 GTC和UTC都是以0时区作为标准时间戳&#xff1a;以UTC的1970-1-1 …

天气数据可视化平台-计算机毕业设计vue

天气变幻无常&#xff0c;影响着我们生活的方方面面&#xff0c;应用天气预报信息可以及时了解天气的趋势&#xff0c;给人们的工作、生活等带来便利&#xff0c;也可以为我们为未来的事情做安排和打算&#xff0c;所以一个精准的、易读 通过利用 程序对气象网站大量的气象信息…

H5游戏源码分享-命悬一线

H5游戏源码分享-命悬一线 在合适的时机跳下绳子&#xff0c;能安全站到木桩上&#xff0c;就通过。 游戏源码 <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><meta name&…

Mybatis延迟加载(缓存)

延迟加载 分步查询的优点&#xff1a;可以实现延迟加载&#xff0c;但是必须在核心配置文件中设置全局配置信息&#xff1a;lazyLoadingEnabled&#xff1a;延迟加载的全局开关。当开启时&#xff0c;所有关联对象都会延迟加载 aggressiveLazyLoading&#xff1a;当开启时&…

Openssl数据安全传输平台017:Linux客户端代码的编译与调试-Bug记录

文章目录 1 在windows上先预编译2 Centos上进入项目文件夹进行编译2.0 最终的编译指令2.1 找不到lprotobuf&#xff0c;找不到protobuf的google文件夹2.1.1 编译指令及提示2.1.2 问题分析2.1.3 解决办法 2.2 json类中方法unreference2.2.1 编译指令及提示2.2.2 问题分析 *** 最…

hadoop权威指南第四版

第一部分 HaDOOP基础知识 1.1 面临的问题 存储越来越大&#xff0c;读写跟不上。 并行读多个磁盘。 问题1 磁盘损坏 – 备份数据HDFS 问题2 读取多个磁盘用于分析&#xff0c;数据容易出错 --MR 编程模型 1.2 衍生品 1 在线访问的组件是hbase 。一种使用hdfs底层存储的模型。…

Spring中Bean的完整生命周期!(Bean实例化的流程,Spring后处理器,循环依赖解释及解决方法)附案例演示

Bean实例化的基本流程 加载xml配置文件&#xff0c;解析获取配置中的每个的信息&#xff0c;封装成一个个的BeanDefinition对象将BeanDefinition存储在一个名为beanDefinitionMap的Map<String,BeanDefinition>中ApplicationContext底层遍历beanDefinitionMap&#xff0c…

寻找倒数第K个节点

这篇文章也是凑数的 ... 寻找倒数第K个节点 描述 : 找出单向链表中倒数第 k 个节点。返回该节点的值。 题目 : LeetCode 返回倒数第K个节点 : 面试题 02.02. 返回倒数第 k 个节点 说明 : 给定的 k 保证是有效的。 分析 : 我们给出个例子 : 首先&#xff0c;我们创建两个…