队列详解(C语言实现)

文章目录

  • 写在前面
  • 1 队列的定义
  • 2 队列的初始化
  • 3 数据入队列
  • 4 数据出队列
  • 5 获取队头元素
  • 6 获取队尾元素
  • 7 获取队列元素个数
  • 8 判断队列是否为空
  • 8 队列的销毁

写在前面

本片文章详细介绍了另外两种存储逻辑关系为 “一对一” 的数据结构——栈和队列中的队列,并使用C语言实现链队列。
队列C语言实现源码:队列源码
以队列在存储数据时具有特殊的顺序规则:
队列:使用队列存储数据,遵循 “先进先出” 的原则,即最先进队列的数据最先出队列。队列也可以分为顺序队列(基于数组实现)和链队列(基于链表实现)。
在这里插入图片描述

队列的实现方式分为顺序和链式结构,分别适用于不同的场景。顺序结构在内存中占据一块连续的空间,而链式结构通过节点之间的指针连接。这使得栈和队列在实际应用中更灵活,可以根据具体需求选择不同的实现方式。

1 队列的定义

链式队列的实现其实和之前单链表的实现很类似,只不过队列中数据的进出要遵循 “先进先出” 的原则。
链式队列节点的定义:

typedef int QDataType;

typedef struct QueueNode
{
	QDataType val;
	struct QueueNode* next;
}QNode;

队列的定义通常包括两个指针和一个整型,一个指针front指向队列的头,一个指针tail指向队列的尾,还有一个整型size用来记录队列的数据个数。
下面是队列结构的定义:

typedef struct Queue
{
	QNode* front;//指向队列头部的指针
	QNode* tail;//指向队列尾部的指针
	int size;//记录队列中元素个数
}Queue;

2 队列的初始化

刚开始队列为空,头指针front和尾指针tail指向NULL,此时队列中元素个数为0,因此将size初始化为0。
代码如下:

void QueueInit(Queue* pq)
{
	assert(pq);//检查参数有效性

	pq->front = pq->tail = NULL;
	pq->size = 0;
}

3 数据入队列

数据入队列分为一下两种情况:

  1. 队列为空时,新建节点,并用要入队列的数据初始化节点,此时front 和 tail都指向新插入的节点,同时将size+1。
  2. 队列不为空时,新建节点,并用要入队列的数据初始化节点,此时tail->next指向新插入的节点,更新tail指向新插入的节点。

数据1 2 3 4 入队列图解:
在这里插入图片描述
代码如下:

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);//检查参数有效性
	//创建新节点
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("QueuePush->malloc");
		exit(-1);
	}
	newnode->next = NULL;
	newnode->val = x;
	//入队列
	//1. 队列为空
	//2. 队列不为空
	if (pq->front == NULL)
	{
		assert(!pq->tail);// 队列为空时,tail front都为空
		pq->front = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

4 数据出队列

我们知道,队列只能在队尾一端入数据,出数据时只能出队头的数据。因为它要保证有数据元素需要出队时,按照 “先进先出” 的原则。
数据出队的步骤如下:

  1. 在执行数据出队列操作之前,需要检查队列是否为空。如果队列为空(即没有数据),则无法执行出队列操作。
  2. 如果队列不为空,即存在数据,就可以执行出队列操作。
    此时数据出队列又分为两种情况:
    • 队列中只有一个数据:
      此时只需要将该数据所在节点释放,并将 front 和 tail 置为NULL即可。
    • 队列中有两个及以上数据:
      保存头节点下一个节点的地址,释放头节点,更新front,使front指向新的队头元素。

数据1 2 3 4 出队列图解:
在这里插入图片描述

代码如下:

void QueuePop(Queue* pq)
{
	assert(pq);//检查参数有效性
	assert(!QueueEmpty(pq));//检查队列是否为空,为空不能pop

	//出队列
	//1. 队列只有1个元素
	//2.队列有2个以上元素
	if (pq->front->next == NULL)
	{
		free(pq->front);
		pq->front = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->front->next;
		free(pq->front);
		pq->front = next;
	}
	pq->size--;
}

5 获取队头元素

获取队头元素的步骤如下:

  1. 在执行取队头元素操作之前,需要检查队列是否为空。如果队列为空(即没有数据),则无法执行此操作。
  2. 头指针front指向的就是队头元素,如要获取队头元素,因此只需返回front->val即可。

在这里插入图片描述代码如下:

QDataType QueueFront(Queue* pq)
{
	assert(pq);//检查参数有效性
	assert(!QueueEmpty(pq));//检查队列是否为空,为空不能取队头元素

	return pq->front->val;
}

6 获取队尾元素

获取队尾元素的步骤如下:

  1. 在执行取队尾元素操作之前,需要检查队列是否为空。如果队列为空(即没有数据),则无法执行此操作。
  2. 尾指针tail指向的就是队头元素,如要获取队尾元素,因此只需返回tail->val即可。

在这里插入图片描述
代码如下:

QDataType QueueBack(Queue* pq)
{
	assert(pq);//检查参数有效性
	assert(!QueueEmpty(pq));//检查队列是否为空,为空不能取队尾元素

	return pq->tail->val;
}

7 获取队列元素个数

队列中的size记录的就是队列中元素的个数,如要获取队列元素个数,返回size即可。
代码如下:

int QueueSize(Queue* pq)
{
	assert(pq);//检查参数有效性

	return pq->size;
}

8 判断队列是否为空

根据队列初始化函数,我们知道,队列为空时,front 和 tail 都指向NULL。
此时size=0,也可以用size来判断,这里作者选择用front 和 tail 来进行判断。
在这里插入图片描述
代码如下:

bool QueueEmpty(Queue* pq)
{
	assert(pq);//检查参数有效性
	return pq->front == NULL && pq->tail == NULL;
}

8 队列的销毁

链队列用来存储数据的节点都是动态申请的,因此队列销毁时,只需要遍历该链队列,依次释放每个节点。最后将 front 和 tail 置为NULL,size 置为0即可。
代码如下:

void QueueDestroy(Queue* pq)
{
	assert(pq);//检查参数有效性
	QNode* cur = pq->front;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->front = pq->tail = NULL;
	pq->size = 0;
}

至此,本片文章就结束了,若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。
创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!
如果本篇博客有任何错误,请批评指教,不胜感激 !!!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

openEuler Linux 部署 FineBi

openEuler Linux 部署 FineBi 部署环境 环境版本openEuler Linux22.03MySQL8.0.35JDK1.8FineBi6.0 环境准备 升级系统内核和软件 yum -y updatereboot安装常用工具软件 yum -y install vim tar net-tools 安装MySQL8 将 MySQL Yum 存储库添加到系统的存储库列表中 sudo…

RocketMq 队列(MessageQueue)

RocketMq是阿里出品(基于MetaQ)的开源中间件,已捐赠给Apache基金会并成为Apache的顶级项目。基于java语言实现,十万级数据吞吐量,ms级处理速度,分布式架构,功能强大,扩展性强。 官方…

【LeetCode:828. 统计子串中的唯一字符 | 贡献法 乘法原理】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

蓝桥杯第四场双周赛(1~6)

1、水题 2、模拟题,写个函数即可 #define pb push_back #define x first #define y second #define int long long #define endl \n const LL maxn 4e057; const LL N 5e0510; const LL mod 1e097; const int inf 0x3f3f; const LL llinf 5e18;typedef pair…

十大排序之冒泡排序与快速排序(详解)

文章目录 🐒个人主页🏅算法思维框架📖前言: 🎀冒泡排序 时间复杂度O(n^2)🎇1. 算法步骤思想🎇2.动画实现🎇 3.代码实现🎇4.代码优化(添加标志量) …

NX二次开发UF_CURVE_ask_curve_fit_data 函数介绍

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_curve_fit_data Defined in: uf_curve.h int UF_CURVE_ask_curve_fit_data(tag_t curve_feature, UF_CURVE_curve_fit_data * curve_fit_data ) overview 概述 Ask c…

【Spring集成MyBatis】MyBatis注解开发

文章目录 1. MyBatis的常用注解2. 基于注解的MyBatis增删改查增删改查完整代码加载映射关系测试代码 3. MyBatis的注解实现复杂映射开发一对一操作的实现一对一操作实现的第二种方式一对多操作的实现多对多操作实现 1. MyBatis的常用注解 2. 基于注解的MyBatis增删改查 使用注…

【Kotlin】引入与基础语法

文章目录 Kotlin的特性Kotlin优势Kotlin的安卓项目变量变量保存了指向对象的引用优先使用val来避免副作用 后端变量Backing Fields延迟初始化 Kotlin的特性 它更加易表现:这是它最重要的优点之一。你可以编写少得多的代码。Kotlin是一种兼容Java的语言Kotlin比Java…

针对哈希冲突的解决方法

了解哈希表和哈希冲突是什么 哈希表:是一种实现关联数组抽象数据类型的数据结构,这种结构可以将关键码映射到给定值。简单来说哈希表(key-value)之间存在一个映射关系,是键值对的关系,一个键对应一个值。 …

顶级安卓数据恢复工具—— 15 个 Android 数据恢复程序榜单

探索并比较顶级 Android 数据恢复软件,并选择最好的 Android 恢复应用程序来恢复您的宝贵数据: 特别是您的智能手机或 Android 设备可以完成许多繁重的工作,其中最有用的是存储数据。Android 设备可以伪装成照片、视频、电子邮件甚至敏感商业…

MVCC多版本并发控制相关面试题整理

多版本并发控制是一种用于支持并发事务的数据库管理系统技术,它允许多个事务同时访问数据库,而不会相互干扰或导致数据不一致。MVCC通过在数据库中维护不同版本的数据来实现这一目标,从而允许每个事务看到一致的数据库快照。 并发导致的问题…

vue实现海康H5视频插件播放视频的实例,实现取流失败了之后重新获取新的流播放视频

vue实现海康H5视频插件播放视频的实例,实现取流失败了之后重新获取新的流播放视频 h5player是一个基于HTML5的流式网络视频播放器,无需安装浏览器插件即可通过websocket协议向媒体服务取流播放多种格式的音视频流。 首先去海康开发平台,把插…

iar如何全擦芯片内存

Project ->Download -> Erase memory

什么是零拷贝 、零拷贝优化方案 - 真正的零拷贝,哪些地方会用到零拷贝技术

文章目录 什么是零拷贝3、零拷贝优化方案 - 真正的零拷贝哪些地方会用到零拷贝技术 现在来谈谈零拷贝,以及在开发中哪些地方使用到零拷贝。 开干… 什么是零拷贝 零拷贝指的是,从一个存储区域到另一个存储区域的copy任务无需CPU参与就可完成。零拷贝的底…

基于springboot实现应急救援物资管理系统项目【项目源码】

基于springboot实现应急救援物资管理系统演示 JAVA简介 JavaScript是一种网络脚本语言,广泛运用于web应用开发,可以用来添加网页的格式动态效果,该语言不用进行预编译就直接运行,可以直接嵌入HTML语言中,写成js语言&a…

python游戏开发pygame初步

文章目录 安装和示例移动物体优化 安装和示例 顾名思义,PyGame就是用来做游戏的Python库,提供了许多游戏开发功能,如图像处理、音频播放、事件处理、碰撞检测等等。从这个角度来说,pygame不仅是一个游戏库,同时也是一…

【教3妹学编程-算法题】统计子串中的唯一字符

3妹:“太阳当空照,花儿对我笑,小鸟说早早早,你为什么背上炸药包” 2哥 :3妹,什么事呀这么开发。 3妹:2哥你看今天的天气多好啊,阳光明媚、万里无云、秋高气爽,适合秋游。 2哥&#x…

【brpc学习实践八】bvar及其应用

什么是bvar bvar是多线程环境下的计数器类库,支持单维度bvar和多维度mbvar,方便记录和查看用户程序中的各类数值,它利用了thread local存储减少了cache bouncing,相比UbMonitor(百度内的老计数器库)几乎不会给程序增加性能开销&a…

4、浏览器插件配置使用

文章目录 一、Hackbar1. Load和Execute功能的使用2. Split功能的使用3. Post功能的使用4. 编码功能的使用 二、FoxyProxy1、设置Burpsuite的代理服务端口2、FoxyProxy插件的简单使用 三、User-Agent Switcher 一、Hackbar 火狐浏览器中按下F12键启用hackbar。 1. Load和Execut…

springboot宠物店管理系统-计算机毕设 附源码 32041

SpringBoot宠物店管理系统 摘 要 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,宠物行业当然也不例外。宠物店管理系统是以实际运用为开发背景,运用软件工程原理…