【C语言】队列的实现(数据结构)

news2024/11/15 21:34:06

前言:

相信大家在生活中经常排队买东西,今天学习的队列就跟排队买东西一样,先来买的人就买完先走,也就是先进先出。废话不多说,进入咱们今天的学习吧。

目录

前言:

队列的概念

队列的实现

队列的定义

入队列

判空

出队列

队列初始化

获取队头数据

获取队尾数据

获取有效数量

队列销毁

队列详细代码

头文件Queue.h

函数文件Queue.c

测试Text.cjt


队列的概念

想要去实现队列,首先要了解队列的结构和内容。

队列有队头个队尾,出队列只能在队头出(头删),入队列只能在队尾入(尾插)。

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

队列的实现

前面我们学习了单链表的基本实现,如果掌握了单链表,那么队列的实现就轻而易举了。

因为队列的本质是先进先出,也就是和头节点删除一样,如果我们利用顺序表的结构来实现队列,删掉一个头节点,后面的数据都要往前移动一位,时间复杂度为O(N),所以我们利用单链表来实现队列,既方便又简洁。

队列的定义

我们既然利用单链表来实现队列,那么一个节点里面就会包含一个指向下一个节点的指针和我们要存放的数据。

typedef int QDataType;
//表示队列节点的定义
typedef struct QListNode
{
	struct QListNode* next;
	QDataType val;
}QNode;

这里将int 定义为 QDataType 方便数据类型的更改。

在实现单链表的时候我们只需要了一个头指针,实现队列的时候我们需要加上一个尾指针,这样方便我们找到头尾数据,同时还可以避免遍历找尾,提高的算法的效率。

更重要的是,在的单链表实现中我们的头删,头插都用到了二级指针,考虑到链表为空,只有二级指针才能更好的方便改变指向节点指针的值,但队列我们增加的一个尾指针的话,改变头节点里面的内容就不需要传二级指针了。

//队列的结构
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

后面我们要计算队列中有效数据的元素个数,所以我们加一个size进去。

入队列

数据插入队列的时候,我们要考虑队列为空的情况,最后要注意size要++!!!

//队尾入队列
void QueuePush(Queue* q, QDataType x)
{
	assert(q);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)//考虑newnode为空的情况
	{
		printf("malloc fail!!!");
		exit(1);
	}
	newnode->next = NULL;
	newnode->val = x;

	if (QueueEmpty(q))//队列为空
	{
		q->head = q->tail = newnode;
	}
	else {           //队列不为空
		q->tail->next = newnode;
		q->tail = newnode;
	}
	q->size++;//插入数据之后不要忘了把size++
}

判空

如果为空则返回非零结果,如果非空则返回0

int QueueEmpty(Queue* q)
{
	assert(q);
	return q->size == 0;
}

出队列

这里也要注意,如果只有一个节点的时候,q->head = NULL的同时要保证q->tail也要为空,不然就会出现野指针的情况!

//队头出队列
void QueuePop(Queue* q)
{
	assert(q);
    assert(q->head);
	if (q->head->next == NULL)
	{
		free(q->head);
		q->head = q->tail = NULL;
	}
	else {
		QNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}
	q->size--;
}

一定要写assert(q->head);这样就保证下面的q->head->next没有问题,这样写是为了防止空指针被解引用!

队列初始化

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

获取队头数据

QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->head);
	return q->head->val;
}

获取队尾数据

QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->tail);
	return q->tail->val;
}

这是也要注意要对q->head和q->tail进行断言。

获取有效数量

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

队列销毁

void QueueDestroy(Queue* q)
{
	assert(q);
	QNode* pcur = q->head;
	while (pcur)
	{
		QNode* next = pcur->next;
		free(q->head);
		pcur = next;
		
	}
	q->head = q->tail = NULL;
	q->size = 0;
}

在while循环里面要注意将pcur的下一个节点用新指针保存起来,这样更方便我们去释放空间。

队列详细代码

头文件Queue.h

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<assert.h>

typedef int QDataType;
//表示队列节点的定义
typedef struct QListNode
{
	struct QListNode* next;
	QDataType val;
}QNode;
//队列的结构
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

//初始化队列
void QueueInit(Queue* q);
//队尾入队列
void QueuePush(Queue* q,QDataType x);
//队头出队列
void QueuePop(Queue* q);
//获取队列头部元素
QDataType QueueFront(Queue* q);
//获取队列尾部元素
QDataType QueueBack(Queue* q);
//获取队列中有效元素个数
int QueueSize(Queue* q);
//检验队列是否为空,如果为空则返回非零结果,如果非空则返回0
int QueueEmpty(Queue* q);
//销毁队列
void QueueDestroy(Queue* q);

函数文件Queue.c

#include"Queue.h"
//初始化队列
void QueueInit(Queue* q)
{
	assert(q);
	q->head = q->tail = NULL;
	q->size = 0;
}
//队尾入队列
void QueuePush(Queue* q, QDataType x)
{
	assert(q);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)//考虑newnode为空的情况
	{
		printf("malloc fail!!!");
		exit(1);
	}
	newnode->next = NULL;
	newnode->val = x;

	if (QueueEmpty(q))//队列为空
	{
		q->head = q->tail = newnode;
	}
	else {           //队列不为空
		q->tail->next = newnode;
		q->tail = newnode;
	}
	q->size++;//插入数据之后不要忘了把size++
}

//队头出队列
void QueuePop(Queue* q)
{
	assert(q);
	if (q->head->next == NULL)
	{
		free(q->head);
		q->head = q->tail = NULL;
	}
	else {
		QNode* next = q->head->next;
		free(q->head);
		q->head = next;
	}
	q->size--;
}
//获取队列头部元素
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->head);
	return q->head->val;
}
//获取队列尾部元素
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->tail);
	return q->tail->val;
}
//获取队列中有效元素个数
int QueueSize(Queue* q)
{
	assert(q);
	return q->size;
}
//检验队列是否为空,如果为空则返回非零结果,如果非空则返回0
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->size == 0;
}
//销毁队列
void QueueDestroy(Queue* q)
{
	assert(q);
	QNode* pcur = q->head;
	while (pcur)
	{
		QNode* next = pcur->next;
		free(q->head);
		pcur = next;
		
	}
	q->head = q->tail = NULL;
	q->size = 0;
}

测试Text.cjt

#include"Stack.h"
#include"Queue.h"
void QueueText()
{
	Queue q;
	QueueInit(&q);//传地址过去才能影响结构体里面的值
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	while (!QueueEmpty(&q))
	{
		printf("%d", QueueFront(&q));
		QueuePop(&q);
		printf("\n");
	}
	QueueDestroy(&q);
}
int main()
{
	QueueText();
	return 0;
}


今天的分享就到这啦!如果大家有所感悟或者见解多多分享哈。

记得三连哦,有不好的地方欢迎大佬指正!

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

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

相关文章

【8月EI会议推荐】第四届区块链技术与信息安全国际会议

一、会议信息 大会官网&#xff1a;http://www.bctis.nhttp://www.icbdsme.org/ 官方邮箱&#xff1a;icbctis126.com 组委会联系人&#xff1a;杨老师 19911536763 支持单位&#xff1a;中原工学院、西安工程大学、齐鲁工业大学&#xff08;山东省科学院&#xff09;、澳门…

git 学习总结

文章目录 一、 git 基础操作1、工作区2、暂存区3、本地仓库4、远程仓库 二、git 的本质三、分支git 命令总结 作者: baron 一、 git 基础操作 如图所示 git 总共有几个区域 工作区, 暂存区, 本地仓库, 远程仓库. 1、工作区 存放项目代码的地方&#xff0c;他有两种状态 Unm…

RK3588+MIPI+GMSL+AI摄像机:自动车载4/8通道GMSL采集/边缘计算盒解决方案

RK3588作为目前市面能买到的最强国产SOC&#xff0c;有强大的硬件配置。在智能汽车飞速发展&#xff0c;对图像数据矿场要求越来越多的环境下&#xff0c;如何高效采集数据&#xff0c;或者运行AI应用&#xff0c;成为刚需。 推出的4/8通道GMSL采集/边缘计算盒产品满足这些需求…

MinIO存储桶通知 - Kafka小测

概述 公司的某个项目需要用上这玩意&#xff0c;所以在本地搭建测试环境&#xff0c;经过一番折腾&#xff0c;测试通过&#xff0c;博文记录&#xff0c;用以备忘 MinIO安装 该节不做说明&#xff0c;网络有很多现成的帖子&#xff0c;自行搜索去 配置步骤 控制台添加事件…

瑞芯微芯片资料中关于图像处理相关的知识点

目录 MPI层模块介绍IPC的应用像素格式排布系统绑定API接口 MPI层 文件&#xff1a;Rockchip_Developer_Guide_MPI.pdf RK MPI&#xff1a;Rockchip Media Process Interface&#xff0c;媒体处理接口。 模块介绍 RK MPI层的模块介绍&#xff1a; IPC的应用 VI 模块捕获视频…

工业三防平板电脑助力工厂产线管理的智能化转型

在当今高度数字化和智能化的工业时代&#xff0c;工厂产线管理正经历着前所未有的变革。其中&#xff0c;工业三防平板电脑作为一种创新的技术工具&#xff0c;正发挥着日益重要的作用&#xff0c;有力地推动着工厂产线管理向智能化转型。 一、工业三防平板电脑具有出色的防水、…

微信小程序-本地部署(前端)

遇到问题&#xff1a;因为是游客模式所以不能修改appID. 参考链接&#xff1a;微信开发者工具如何从游客模式切换为开发者模式&#xff1f;_微信开发者工具如何修改游客模式-CSDN博客 其余参考&#xff1a;Ego微商项目部署&#xff08;小程序项目&#xff09;&#xff08;全网…

大语言模型是什么,该如何去学习呢

什么是 LLM**&#xff1f;** LLM(大型语言模型&#xff0c; Large Lanage Modle)是一种计算机程序&#xff0c;它可以理解和生成类似人类的文本&#xff1b;它能够像我们人类一样阅读、写作和理解语言。你可以把它想象成一个超级聪明的博学的不知疲惫的24小时全年无休的助手。…

使用代理IP进行本地SEO优化:如何吸引附近的客户?

在今天竞争激烈的互联网时代&#xff0c;如何利用代理IP进行本地SEO优化并吸引附近的客户已经成为许多企业和网站面临的关键挑战。本文将探讨使用代理IP的策略和技巧&#xff0c;以帮助公司提高在本地市场的可见性和吸引力&#xff0c;从而扩大本地客户群体。 1. 代理IP在本地…

小型内衣裤洗衣机哪个牌子好?五款万分翘楚机型任你挑选!

在日常生活中&#xff0c;内衣洗衣机已成为现代家庭必备的重要家电之一。选择一款耐用、质量优秀的内衣洗衣机&#xff0c;不仅可以减少洗衣负担&#xff0c;还能提供高效的洗涤效果。然而&#xff0c;市场上众多内衣洗衣机品牌琳琅满目&#xff0c;让我们往往难以选择。那么&a…

vdb:虚拟数据库

将文件虚拟成数据库&#xff0c;序列化写入、反序列化读取、直接读取。

AI 大模型催生的新职业,提示词工程师是什么?

全方位解析“提示词工程师”。 ‍ AI大模型技术正以前所未有的速度重塑我们的未来。 它们不仅仅是冷冰冰的算法集合&#xff0c;更是拥有无限创造力的智能体。而在这个智能体的背后&#xff0c;有一群关键的角色——提示词工程师&#xff08;Prompt Engineer&#xff09;。 …

网易《永劫无间》手游上线,掀起游戏界狂潮

原标题&#xff1a;网易《永劫无间》手游上线&#xff0c;网友&#xff1a;发烧严重 易采游戏网7月26日消息&#xff1a;自网易宣布《永劫无间》手游即将上线以来&#xff0c;广大游戏玩家的期待值就不断攀升。作为一款拥有丰富内容和极高自由度的游戏&#xff0c;《永劫无间》…

奔赴端到端时代:智驾如果还走原来的路,就到不了ChatGPT时刻

采访 | 德新 编辑 | Dude 在智能汽车的赛道里&#xff0c;特斯拉是独树一帜的旗手&#xff0c;几乎引领了大部分技术变革的风潮。最近一次&#xff0c;是特斯拉掀起的「端到端」热潮。抛弃规则&#xff0c;拥抱数据&#xff0c;在这一年内迅速成为业界共识。 只是在技术落地的…

2024杭电多校3——1001深度自同构

一开始和队友想出来的式子, p i p_i pi​是 i i i的因子数组 a n s [ i ] ∑ i 1 k a n s [ ( i − p i ) / p i ] ans[i] \sum_{i1}^{k} ans[(i-p_i)/p_i] ans[i]∑i1k​ans[(i−pi​)/pi​] 一个 O ( n n ) O(n\sqrt n) O(nn ​)的dp显然是过不了的 然后想到了对每个数枚…

当你还在方兴未艾之时!智慧城市可视化大屏已经风起云涌了

当你还在方兴未艾之时&#xff01;智慧城市可视化大屏已经风起云涌了 艾斯视觉的观点认为&#xff1a;科技的浪潮一波接着一波&#xff0c;不断刷新着我们的认知。当你还在为刚刚兴起的智能设备惊叹不已时&#xff0c;智慧城市的可视化大屏已经如同一股不可阻挡的狂风&#xf…

yarn安装electron时报错RequestError:socket hang up

安装electron时候&#xff0c;出现RequestError:socket hang up这样的错误&#xff0c;找了半天很多方式都是用旧淘宝源&#xff0c;导致根本安装不上去。 在项目的根目录下创建.npmrc文件&#xff0c;添加以下内容 # registryhttps://mirrors.huaweicloud.com/repository/np…

狗都能看懂的Actor-Critic强化学习算法讲解

Review Policy Gradient 上面的公式是Policy Gradient的更新函数&#xff0c;这个式子是指在 s t s_t st​时刻采取了 a t a_t at​&#xff0c;计算出对应发生的概率 p θ p_\theta pθ​&#xff0c;然后计算在采取了这个 a t a_t at​之后&#xff0c;所得到的reward有多大。…

【运维笔记】数据库无法启动,数据库炸后备份恢复数据

事情起因 在做docker作业的时候&#xff0c;把卷映射到了宿主机原来的mysql数据库目录上&#xff0c;宿主机原来的mysql版本为8.0&#xff0c;docker容器版本为5.6&#xff0c;导致翻车。 具体操作 备份目录 将/var/lib/mysql备份到~/mysql_backup&#xff1a;cp /var/lib/…

沃尔玛1P账号智能宠物用品市场的商机与策略——WAYLI威利跨境助力商家

近年来&#xff0c;随着人们生活水平的提高和对宠物陪伴需求的增长&#xff0c;宠物经济正在全球范围内蓬勃发展。其中&#xff0c;智能宠物用品市场作为新兴赛道&#xff0c;蕴藏着巨大的商机。对于拥有沃尔玛1P账号的卖家而言&#xff0c;这是一个不容错过的蓝海市场。 智能宠…