【数据结构】队列(Queue)实现详解

news2024/9/24 17:19:52

🚩纸上得来终觉浅, 绝知此事要躬行。
🌟主页:June-Frost
🚀专栏:数据结构

🔥该文章主要了解实现队列的相关操作。

目录:

  • 🌍 队列
    • 🔭概念
    • 🔭结构
    • 🔭 应用场景
  • 🌏 结构实现
    • 🔭 初始化 和 销毁
    • 🔭 入队列
    • 🔭 出队列
    • 🔭 取队头和队尾数据
    • 🔭判空和数据个数
    • 🔭接口测试
  • ❤️ 结语

🌍 队列

🔭概念

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


🔭结构

 队列的底层实现如果使用数组,虽然插入操作很容易,但是在删除操作的时候就需要不断覆盖数据,效率不太高。所以,队列更适合使用单链表结构实现。对于尾插,只需要定义一个尾指针就可以规避遍历,而且队列的操作中也不需要去找前一个节点,所以单向链表就足以实现队列。


🔭 应用场景

 队列的应用场景包括许多方面:

  • 公平性排队:
      队列主要用于确保所有的请求或等待者都能得到平等和公正的服务。例如,在银行或政府部门,所有人都需要按顺序办理业务,而不是先到先得或者根据个人地位或身份进行优先办理。通过队列,每个人都可以在公平的环境中办理业务,而不必担心由于其他因素导致的歧视或不公平待遇。此外,在需要分配资源或任务的情况下,队列也可以保证资源的公平分配和任务的合理安排。

  • BFS (广度优先遍历)
     BFS是一种用于遍历或搜索树或图的算法,它从根节点开始,沿着树的宽度遍历树的节点,直到找到目标节点或发现所有节点都被遍历过。在BFS过程中,队列用于存储待处理的节点,并按照先进先出的原则依次处理每个节点。这种算法在解决图论问题时非常常见,如找到两个节点之间的最短路径、检测图是否连通、搜索图中的环等。

  • 流量削锋
     在某些情况下,例如在大促活动或者突发流量洪流来袭时,下游系统可能无法处理所有的请求。通过队列,我们可以将请求放入队列中,让下游系统在有能力处理消息的时候再处理,避免下游订阅系统因突发流量崩溃。


🌏 结构实现

 结构体的的声明:

typedef int QDataType;
//节点
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;
//指针
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;//计数
}Que;

 实现队列的时候,最好将两个指针放入一个结构体,这样有很多优点:① 实现队列操作的时候只需要传结构体的地址,可以规避二级指针;②可以减少传参的数量,代码更加简明;③此外如果在结构体中加入一个计数器,那么统计队列数据个数的时候就不需要遍历了。

🔭 初始化 和 销毁

 销毁就是链表的释放

//初始化
void QueueInit(Que* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
//销毁
void QueueDestroy(Que* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->tail = pq->head = NULL;
	pq->size = 0;
}

🔭 入队列

//入队列
void QueuePush(Que* pq, QDataType x)
{
	assert(pq);
	QNode* node = (QNode*)malloc(sizeof(QNode));
	if (node == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	node->data = x;
	node->next = NULL;
	//第一个节点
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = node;
	}
	//不是第一个节点
	else
	{
		pq->tail->next = node;
		pq->tail = node;
	}
	pq->size++;
}

 入队列要注意分情况:如果是第一个节点,头指针和尾指针都需要被赋值,如果不是第一个,只需要通过尾指针插入节点并更新尾指针。

🔭 出队列

//出队列
void QueuePop(Que* pq)
{
	assert(pq && pq->size > 0);

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

在这里插入图片描述

🔭 取队头和队尾数据

//取队头
QDataType QueueFront(Que* pq)
{
	assert(pq && pq->size>0);

	return pq->head->data;
}

//取队尾
QDataType QueueBack(Que* pq)
{
	assert(pq && pq->size > 0);

	return pq->tail->data;
}

🔭判空和数据个数

//判空
bool QueueEmpty(Que* pq)
{
	assert(pq);

	return pq->head == NULL;
}

//节点个数
int QueueSize(Que* pq)
{
	assert(pq);

	return pq->size;
}

 由于结构体定义了计数器,在插入和删除时就在不断更新个数值,规避了遍历求解个数的方式。

🔭接口测试

 通过这样的逻辑就实现了先进先出的特性。

void test()
{
	Que q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	QueueDestroy(&q);

}

❤️ 结语

 文章到这里就结束了,如果对你有帮助,你的点赞将会是我的最大动力,如果大家有什么问题或者不同的见解,欢迎大家的留言~

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

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

相关文章

有必要买一台内衣裤专洗机吗?家用小洗衣机推荐

随着内衣洗衣机的流行,很多小伙伴在纠结该不该入手一款内衣洗衣机,专门来洗一些贴身衣物,答案是非常有必要的,因为我们现在市面上的大型洗衣机只能做清洁,无法对我们的贴身衣物进行一个高强度的清洁,而小小…

什么是MTU(Maximum Transmission Unit)?

最大传输单元MTU(Maximum Transmission Unit,MTU),是指网络能够传输的最大数据包大小,以字节为单位。MTU的大小决定了发送端一次能够发送报文的最大字节数。如果MTU超过了接收端所能够承受的最大值,或者是超…

外汇天眼:喜报!外汇天眼获得菲律宾官方“值得信赖的外汇交易商查询平台”奖项

最近,MaxMedia和RTC-KORPILL DAVAO联合在菲律宾棉兰老岛达沃市Tibungco的RTC-KorPhil举办了为期两天的“棉兰老岛贸易商博览会”,在MaxMedia和RTC-KORPILL DAVAO的召集下,博览会吸引了各国外汇交易商、经验丰富的交易师、交易员或喜爱进行加密…

idea 插件推荐(持续更新)

文章目录 Material Theme UIcodeium(建议有梯子的使用)Key Promoter XCodeGlanceRainbow BracketsMarkdown NavigatorRestfulToolkitString Manipulation Material Theme UI 谁不想拥有一款狂拽炫酷 吊炸天 的编码主题呢,给你推荐Material Theme UI Plugin Material Theme UI是…

运维大数据平台的建设与实践探索

随着企业数字化转型的推进,运维管理面临着前所未有的挑战和机遇。为应对日益复杂且严峻的挑战,数字免疫系统和智能运维等概念应运而生。数字免疫系统和智能运维作为新兴技术,正引领着运维管理的新趋势。数字免疫系统和智能运维都借助大数据运…

【003】EIS数据分析_#LIB

EIS数据分析 1. EIS测试及数据获取2. EIS数据分析2.1 EIS曲线划分 1. EIS测试及数据获取 点击查看往期介绍 2. EIS数据分析 2.1 EIS曲线划分 一般来说,实轴处的截获表示体电阻(Rb),它反映了电解质,隔膜和电极的电导率。高频区的半圆对应于…

mysql面试题29:大表查询的优化方案

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一下大表查询的优化方案 以下是几种常见的大表优化方案: 分区&…

mycat的部署及测试

一、基本概念 Mycat 介绍:是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。Mycat是使用 JAVA 语言进行编写开发,使用前需要先安装 JAVA 运行环境(JRE),并且要求必须在 JDK7 以上的版本上运行。 mycat工作原理&#x…

敏捷开发使用

1.敏捷开发 敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。换言之,就…

基于NIFI工具搭建生产级别的IIOT系统

本示例内容在使用NIFI构建一个高度可扩展的物联网应用数据管道示例的基础上进行。 前文中的示例,如果放到生产环境中,那么MQTT和MINIFI部署在智能设备中,NIFI部署在数据中心服务器上。 如果需要修改MINIFI中的ETL任务,那么我们需…

Java架构师海量数据的存储方案

目录 1 导学2 海量数据和大数据的区别3 海量数据处理的核心思想4 数据库架构设计的方法论5 海量数据处理的方法6 海量数据的存储方案7 海量数据当中的写的方案8 海量数据当中读的方案9 总结1 导学 本章的主要内容呢是大型系统架构设计难点之一的海量数据架构设计相关的知识落到…

配置mysql+Navicat+XShell宝塔:Mark

Centos7开放3306端口(iptables 防火墙 未设置) Centos7开放3306端口_centos开启3306端口-CSDN博客 firewall-cmd --zonepublic --add-port3306/tcp --permanent Navicat连接1130错误的解决方法 Navicat连接1130错误的解决方法 - 风纳云 ERROR 1062 …

零基础转行网络安全可以做什么工作

一直在说网络安全行业好就业、薪资高、前景也好,但是大家对网络安全这个行业具体做什么工作可能还一知半解。所以今天来跟大家聊聊,网络安全学完可以找到什么样的工作,顺便把不同岗位的不同技术要求也说一下。 安全运维工程师 由于一些知名…

儿童龋齿:原因与预防护理

引言: 儿童的健康是每个家庭都十分关心的问题,其中口腔健康尤为重要。儿童龋齿,也被称为童年龋齿,是一种常见但可预防的口腔健康问题。本文将探讨儿童龋齿的原因,以及提供有关如何预防和护理儿童口腔健康的重要信息。…

Java架构师缓存架构设计解决方案

目录 1 缓存常见的三大问题1.1 缓存雪崩1.2 缓存穿透1.3 缓存击穿2 缓存key的生成策略3 热点数据集中失效的问题4 如何提高缓存的命中率5 缓存和数据库双写不一致的问题6 如何对缓存数据进行分片7 如何应对缓存数据的热点问题1 缓存常见的三大问题 缓存常见的三大问题就是缓存雪…

uni-app生命周期

uni-app的生命周期包括:应用生命周期、页面生命周期、组件生命周期 一、应用生命周期(只能在App.vue文件中监听) 函数说明onLaunch初始化完成时触发(全局只触发一次)onShow启动时或从后台进入前台显示onHide从前台进入…

Jenkins 执行远程shell脚本部署jar文件问题起不来

如图:最开始的时候没有加: source /etc/profile 这一行, run.sh里面的java -jar xxxx.jar 一直执行不来。 一开始以为是Jenkins执行退出后会kill一切它启动的进程,所以加了在run.sh里面加了export BUILD_IDdontKillMe&#xff0…

ArcGIS: 第二届全国大学生GIS技能大赛(广西师范学院)详解-下午题

目录 01 题目 02 思路和实操 2.1 流域提取-思路 2.2 流域提取-实操 2.2.1 获取DEM ​编辑 2.2.2 水文分析-提取流域基于单出水口 2.3 河网分级-思路 2.4 河网分级-实操 2.4.1 提取河道网络 2.4.2 河网分级 ​编辑 2.5 子流域提取和处理-思路 2.6 子流域提取和处理-实…

软考高项-第十章:项目进度管理

重要知识点: 以上总结,仅供参考。

第三章-完善MBR

为什么mbr编译时设置数据的起始地址vstart0x7c00,就可以保证程序加载器能将MBR加载到内存的0x7c00? 程序加载器负责将根据编译后的程序地址加载到内存中,mbr 用 vstart0x7c00 来修饰的原因,是开发人员知道 mbr 要被加载器&#x…