【数据结构初阶第十节】队列(详解+附源码)

news2025/5/10 20:52:14

 好久不见。。。别不开心了,听听喜欢的歌吧

必须有为成功付出代价的决心,然后想办法付出这个代价。云边有个稻草人-CSDN博客

目录

一、概念和结构

二、队列的实现

Queue.h

Queue.c

 test.c

Relaxing Time!

————————————《有没有那么一首歌会让你想起我》————————————


这节课我们学习队列的概念和结构以及实现,需要提前具备前面顺序表和链表的相关知识,这样这节课就会变得非常简单!

一、概念和结构

概念: 只允许在⼀端进行插⼊数据操作,在另⼀端进⾏删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)。
入队列: 进行 插⼊操作的⼀端称为队尾。
出队列: 进行 删除操作的⼀端称为队头。
队列底层结构选型 : 队列也可以数组和链表的结构实现,使⽤链表的结构实现更优⼀些,因为如果使⽤数组的结构,出队列在数组头上出数据,效率会⽐较低。
下图解释为什么用链表来实现队列

二、队列的实现

Queue.h

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

//创建节点的结构
typedef int QUDatatype;
typedef struct QueueNode
{
	QUDatatype data;
	struct QueueNode* next;
}QueueNode;

//创建队列的结构
typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
	int size;//队列里面有效数据个数
}Queue;

//初始化
void QueueInit(Queue* pq);

//入队列
void QueuePush(Queue* pq,QUDatatype x);

//出队列
void QueuePop(Queue* pq);

//取队头数据
QUDatatype QueueFront(Queue* pq);

//取队尾数据
QUDatatype QueueBack(Queue* pq);

//取队列有效元素个数
int QueueSize(Queue* pq);

//销毁
void QueueDestroy(Queue* pq);

Queue.c

#include"Queue.h"

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

//入队列
void QueuePush(Queue* pq,QUDatatype x)
{
	assert(pq);
	//申请一个新的结点
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;

	if (pq->phead == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	++pq->size;
}

//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	//下面这样写也ok,return pq->phead == NULL && pq->ptail == NULL ;
	return pq->phead == NULL;
}

//出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	
	//若只有一个结点,防止ptail成为野指针
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		//删除对头元素
		QueueNode* Next = pq->phead->next;
		free(pq->phead);
		pq->phead = Next;
	}
	--pq->size;
}

//取队头数据
QUDatatype QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->phead->data;

}

//取队尾数据
QUDatatype QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->ptail->data;
}

//取队列有效元素个数,时间复杂度为O(N),我们可以优化一下
//我们可以增加一个变量size去记录队列里面有效数据的个数然后直接返回
int QueueSize(Queue* pq)
{
	assert(pq);
	/*QueueNode* pcur = pq->phead;
	int count = 0;
	while (pcur)
	{
		count++;
		QueuePop(pq);
		pcur = pq->phead;
	}*/
	/*return count;*/

	return pq->size;
}

//销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	QueueNode* pcur = pq->phead;
	while (pcur)
	{
		QueueNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	//针对队列里面的结构进行销毁
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

 test.c

#include"Queue.h"

void test()
{
	Queue pq;
	QueueInit(&pq);
	QueuePush(&pq, 1);
	QueuePush(&pq, 2);
	QueuePush(&pq, 3);
	QueuePush(&pq, 4);

	/*QueuePop(&pq);
	QueuePop(&pq);
	QueuePop(&pq);
	QueuePop(&pq);
	QueuePop(&pq);*/

	printf("head:%d\n", QueueFront(&pq));
	printf("back:%d\n", QueueBack(&pq));

	//两种 取队列里面有效数据的个数 方法
	printf("队列里面有效数据个数为:%d \n",QueueSize(&pq));
	printf("size:%d\n", QueueSize(&pq));
	printf("size:%d\n", pq.size);

	QueueDestroy(&pq);

}

int main()
{
	test();
	return 0;
}

实现队列需要注意的比较重要的点见下

  1. 取队列里面有效数据的个数,如果用老方法套路实现时间复杂度为O(N),但是我们可以在队列里面重新定义一个结构,size来记录,每次入数据,出数据直接调整size即可,取有效数据个数的时候直接返回 size 就简单了很多。
  2. 在队列销毁的时候,不要忘记最后把队列结构里面的phead和ptail指针置为NULL,size == 0。
  3. 我们定义了ptail指针,指向队尾,可以直接找到队尾入数据。

经过前几节顺序表,单链表,双链表,栈的学习,今天学习队列真是游刃有余呦,下一节是栈和队列的算法题,期待一下啦~~

完——


Relaxing Time!

————————————《 有没有那么一首歌会让你想起我 ————————————

有没有一首歌会让你想起我_HENRY刘宪华_高音质在线试听_有没有一首歌会让你想起我歌词|歌曲下载_酷狗音乐

至此结束!

我是云边有个稻草人

期待与你的下一次相遇。。。

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

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

相关文章

250213-RHEL8.8-外接SSD固态硬盘

It seems that the exfat-utils package is still unavailable, even after enabling the RPM Fusion repository. This could happen if the repository metadata hasn’t been updated or if the package isn’t directly available in the RPM Fusion repository for RHEL 8…

游戏引擎学习第99天

仓库:https://gitee.com/mrxiao_com/2d_game_2 黑板&#xff1a;制作一些光场(Light Field) 当前的目标是为游戏添加光照系统&#xff0c;并已完成了法线映射&#xff08;normal maps&#xff09;的管道&#xff0c;但还没有创建可以供这些正常映射采样的光场。为了继续推进&…

Linux初始化 配置yum源

问题出现&#xff1a;&#xff08;报错&#xff09; 1 切换路径 2 备份需要操作的文件夹 3 更改 CentOS 的 YUM 仓库配置文件&#xff0c;以便使用阿里云的镜像源。 4 清除旧的yum缓存 5 关闭防火墙 6 生成新的yum缓存 7 更新系统软件包 8 安装软件包

【笛卡尔树】

笛卡尔树 笛卡尔树定义构建性质 习题P6453 [COCI 2008/2009 #4] PERIODNICF1913D Array CollapseP4755 Beautiful Pair[ARC186B] Typical Permutation Descriptor 笛卡尔树 定义 笛卡尔树是一种二叉树&#xff0c;每一个节点由一个键值二元组 ( k , w ) (k,w) (k,w) 构成。要…

Java String 类深度解析:内存模型、常量池与核心机制

目录 一、String初识 1. 字符串字面量的处理流程 (1) 编译阶段 (2) 类加载阶段 (3) 运行时阶段 2. 示例验证 示例 1&#xff1a;字面量直接赋值 示例 2&#xff1a;使用 new 创建字符串 示例 3&#xff1a;显式调用 intern() 注意点1&#xff1a; ⑴. String s1 &q…

探索顶级汽车软件解决方案:驱动行业变革的关键力量

在本文中&#xff0c;将一同探索当今塑造汽车行业的最具影响力的软件解决方案。从设计到制造&#xff0c;软件正彻底改变车辆的制造与维护方式。让我们深入了解这个充满活力领域中的关键技术。 设计软件&#xff1a;创新车型的孕育摇篮 车辆设计软件对于创造创新型汽车模型至…

TikTok走红全球:中国短视频平台以全新姿态登陆海外市场

在数字化浪潮中&#xff0c;短视频已经成为全球年轻人表达自我、分享生活的重要方式。TikTok&#xff0c;这个起源于中国的短视频平台&#xff0c;以其独特的魅力和创新的功能在全球范围内迅速走红。本文将探讨TikTok如何以全新姿态登陆海外市场&#xff0c;并分析其成功的关键…

计算机毕业设计Python旅游评论情感分析 NLP情感分析 LDA主题分析 bayes分类 旅游爬虫 旅游景点评论爬虫 机器学习 深度学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

day9手机创意软件

趣味类 in:记录趣味生活&#xff08;通用&#xff09; 魔漫相机&#xff1a;真人变漫画&#xff08;通用&#xff09; 活照片&#xff1a;让照片活过来&#xff08;通用&#xff09; 画中画相机&#xff1a;与众不同的艺术 年龄检测仪&#xff1a;比一比谁更年轻&#xf…

A001基于SpringBoot实现的小区物业管理系统

系统介绍 基于SpringBoot实现的小区物业管理系统是为物业管理打造的一款在线管理平台&#xff0c;它可以实时完成信息处理&#xff0c;对小区信息、住户等进行在线管理&#xff0c;使其系统化和规范化。 系统功能说明 1、系统共有物业、业主角色&#xff0c;物业拥有系统最高…

【Uniapp】关于实现下拉刷新的三种方式

在小程序、h5等地方中&#xff0c;常常会用到下拉刷新这个功能&#xff0c;今天来讲解实现这个功能的三种方式&#xff1a;全局下拉刷新&#xff0c;组件局部下拉刷新&#xff0c;嵌套组件下拉刷新。 全局下拉刷新 这个方式简单&#xff0c;性能佳&#xff0c;最推荐&#xf…

深入理解DeepSeek与企业实践(二):32B多卡推理的原理、硬件散热与性能实测

前言 在《深入理解 DeepSeek 与企业实践&#xff08;一&#xff09;&#xff1a;蒸馏、部署与评测》文章中&#xff0c;我们详细介绍了深度模型的蒸馏、量化技术&#xff0c;以及 7B 模型的部署基础&#xff0c;通常单张 GPU 显存即可满足7B模型完整参数的运行需求。然而&…

数据结构-链式二叉树

文章目录 一、链式二叉树1.1 链式二叉树的创建1.2 根、左子树、右子树1.3 二叉树的前中后序遍历1.3.1前(先)序遍历1.3.2中序遍历1.3.3后序遍历 1.4 二叉树的节点个数1.5 二叉树的叶子结点个数1.6 第K层节点个数1.7 二叉树的高度1.8 查找指定的值(val)1.9 二叉树的销毁 二、层序…

【云安全】云原生- K8S etcd 未授权访问

什么是etcd&#xff1f; etcd 是一个开源的分布式键值存储系统&#xff0c;主要用于存储和管理配置信息、状态数据以及服务发现信息。它采用 Raft 共识算法&#xff0c;确保数据的一致性和高可用性&#xff0c;能够在多个节点上运行&#xff0c;保证在部分节点故障时仍能继续提…

AI时代的前端开发:对抗压力的利器

在飞速发展的AI时代&#xff0c;前端开发工程师们面临着前所未有的挑战。项目周期不断缩短&#xff0c;需求变化日新月异&#xff0c;交付压力更是与日俱增&#xff0c;这使得开发人员承受着巨大的压力。如何提升对抗压能力&#xff0c;成为摆在每一位前端工程师面前的重要课题…

在npm上传属于自己的包

前言 最近在整理代码&#xff0c;上传到npm方便使用&#xff0c;所以学习了如何在npm发布一个包&#xff0c;整理写成一篇文章和大家一起交流。 修改记录 更新内容更新时间文章第一版25.2.10新增“使用包”&#xff0c;“删除包的测试”25.2.12 1、注册npm账号 npm | Home 2…

[Spring] Spring常见面试题

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

22.4、Web应用漏洞分析与防护

目录 Web应用安全概述DWASP Top 10Web应用漏洞防护 - 跨站脚本攻击XSSWeb应用漏洞防护 - SQL注入Web应用漏洞防护 - 文件上传漏洞Web应用漏洞防护 - 跨站脚本攻击XSS Web应用安全概述 技术安全漏洞&#xff0c;主要是因为技术处理不当而产生的安全隐患&#xff0c;比如SQL注入…

SpringBoot实战:高效获取视频资源

文章目录 前言技术实现SpringBoot项目构建产品选取配置数据采集 号外号外 前言 在短视频行业高速发展的背景下&#xff0c;海量内容数据日益增长&#xff0c;每天都有新的视频、评论、点赞、分享等数据涌现。如何高效、精准地获取并处理这些庞大的数据&#xff0c;已成为各大平…

迅为RK3568开发板篇OpenHarmony实操HDF驱动配置LED-LED测试

将编译好的镜像全部进行烧写&#xff0c;镜像在源码根目录 out/rk3568/packages/phone/images/目录下。 烧写完成之后&#xff0c;在调试串口查看打印日志&#xff0c;如下图所示&#xff1a; 然后打开 hdc 工具&#xff0c;运行测试程序&#xff0c;输入“led_test 1”&…