速学数据结构 | 链表实现队列究竟有什么优势?


在这里插入图片描述

🎬 鸽芷咕:个人主页

 🔥 个人专栏:《速学数据结构》 《C语言进阶篇》

⛺️生活的理想,就是为了理想的生活!

📋 前言

  🌈hello! 各位宝子们大家好啊,栈区的实现我们前面已经讲了,而栈和队列都是特殊的线性表,今天我们就来看看队列是怎么实现的!
  ⛳️队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的特点。
  📚本期文章收录在《数据结构&算法》,大家有兴趣可以看看呐
  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

文章目录

  • 📋 前言
  • 一、 队列的概念及结构
  • 二、 队列的实现
    • 2.1 队列的结构
    • 2.2 队列的初始化
    • 2.3 队尾入队列
    • 2.4 对头出队列
    • 2.5 获取队列头部元素
    • 2.6 获取队列队尾元素
    • 2.7 获取队列中有效元素个数
    • 2.8 判断队列是否为空
    • 2.9 销毁队列
  • 📝全篇总结

一、 队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out),其实理解起来很简单就像我们排队一样先排队的像打到饭然后出队列。

  • 而队列的主要操作就是下面俩条:
  • 入队列:进行插入操作的一端称为队尾
  • 出队列:进行删除操作的一端称为队头

在这里插入图片描述

二、 队列的实现

队列其实也可以用我们学过的数组或者链表实现但是,用数组的话头删要把整个尾部的数据拉过来覆盖前面消耗太大了。所以我们选择使用链表实现出队列头删的时候只要是否头结点到下一个节点就好了。

  • 队列也可以数组和链表的结构实现,使用链表的结构实现更优一些
  • 如果使用数组的结构,出队列在数组头上出数据,效率会比较低

在这里插入图片描述

2.1 队列的结构

那么队列的结构该如何定义呢?首先我们选择用链表来实现队列肯定要先定义一个单链表来进行连接和存放数据:

  • 而队列又需要获取头部和尾部的数据所以:
  • 又需要定义一个头指针和尾指针来指向链表的头和尾。
  • 还要获取队列长度怎么办呢?
  • 就在定义一个 size 来记录队列的长度就可以非常简单的解决问题了

📚 代码演示:

typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;int size;
}Que;

2.2 队列的初始化

队列的初始化,刚开始的时候队列什么数据都没有所以 headtail 他们指向空就好了。

  • size 目前也没有数据初始化为零可以了
  • 还要注意传进来的是否为空指针

📚 代码演示:

// 初始化队列 
void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}

2.3 队尾入队列

入队列就很简单了,每次需要了就去 malloc 一个节点然后尾插到 队列后面就好了。

  • 但是也要注意一种情况:
  • 一个是队列为空是的插入

📚 代码演示:

// 队尾入队列 
void QueuePush(Que* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;if (pq->tail == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}

2.4 对头出队列

出队列就简单了,先判断一下队列是否为空。为空就直接返回

  • 不为空就直接 free() 掉前一个节点,然后 front 向前走到下一个节点
  • 还要考虑最后一个节点的时候删除怎么办
  • 然后 size-- 数据不要忘记了

📚 代码演示:

void QueuePop(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}

2.5 获取队列头部元素

由于我们已经定义了一个头指针,所以直接找到 front 里面存放的元素返回就OK了,是不是非常简单。

📚 代码演示:

// 获取队列头部元素 
QDataType QueueFront(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}

2.6 获取队列队尾元素

队尾元素可对头是一样的,先判断指针是否为空,和队列是否为空。

📚 代码演示:

// 获取队列队尾元素 
QDataType QueueBack(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}

2.7 获取队列中有效元素个数

大家看到这个是不是觉得就是小卡拉米,一下就搞定了:

  • 前面我们定义了一个 size 用来记录队列的元素这个时候就派上用场了。

📚 代码演示:

// 获取队列中有效元素个数 
int QueueSize(Que* pq)
{assert(pq);return pq->size;
}

2.8 判断队列是否为空

大家想一想什么时候队列尾空呢?是不是只有 front == break 的时候才为空啊!

  • 因为只有这样 队列的数据是一个都没存储的

📚 代码演示:

// 检测队列是否为空,如果为空返回非零false,如果非空返回true
bool QueueEmpty(Que* pq)
{assert(pq);return pq->head == NULL;
}

2.9 销毁队列

销毁队列就和以前一样了,先把每个节点都用循环销毁了。在把俩个队列指针置空

  • 数据有效个数szie为0 ,这样就可以销毁队列了

📚 代码演示:

void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}

📝全篇总结

☁️ 好啦以上就是队列实现的全部过程了,相比较链表来说这些更像是链表的扩展只要链表掌握的好这些都是非常简单的!
看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shell学习脚本05(小滴课堂)

可以对海量的数据进行提取。 -v对提取的内容进行取反。 -n显示出行号。 -w精确匹配: -i:忽略大小写: -E正则匹配: cut命令: -d指定分隔符,-f指定截取区域: 截取第一列到第三列: 截取第二列到最…

趋势:实时的stable diffusion

视频中使用了实时模型:只需2~4 个步骤甚至一步即可生成768 x 768分辨率图像。 这项技术可以把任意的stable diffusion模型转为实时模型。 潜在一致性模型 LCM LCM 只需 4,000 个训练步骤(约 32 个 A100 GPU 一小时)即可从任何预训练的SD模型中…

在markdown中怎么画表格

2023年11月5日,周日上午 下面是一种常用的方式来编写表格: | 列1标题 | 列2标题 | 列3标题 | |:------:|:------:|:------:| | 内容 | 内容 | 内容 | | 内容 | 内容 | 内容 |在这个示例中,第一行用于定义表格的列标…

论文阅读—— UniDetector(cvpr2023)

arxiv:https://arxiv.org/abs/2303.11749 github:https://github.com/zhenyuw16/UniDetector 一、介绍 通用目标检测旨在检测场景那种的一切目标。现有的检测器依赖于大量数据集 通用的目标检测器应该有两个能力:1、可以利用多种来…

asp.net人事管理信息系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 人事管理信息系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言 开发 asp.net 人事管理系统1 应用技术…

宠物医院服务预约小程序的效果如何

随着养宠家庭增多及对爱宠的照顾加深,除了食品、服饰外,宠物医院近些年也迎来了较高发展,部分城市甚至聚集着众多品牌,以单店或多店品牌的方式拓展市场。 对宠物医院来说,一般都是拓展同市客户,或者多门店…

强化学习的动态规划三

一、策略的改进 假设新的贪婪策略π0与旧的策略π效果相当,但并不优于π。由此得出vπvπ0,且根据之前的推导可以得出:对于所有的s∈S 这与贝尔曼最优方程相同,因此,vπ0是v∗,π和π0是最佳策略。因此&…

类和对象 下

构造函数 初始化列表 构造函数是在构造类的时候给对象赋初值,并不是给类的成员函数初始化,赋值可以赋多次,而初始化只能初始化一次,这里我们引入初始化列表来对成员函数进行初始化 初始化列表,以冒号 :开…

JavassmMYSQL宠物领养系统08465-计算机毕业设计项目选题推荐(附源码)

目 录 摘要 1 绪论 1.1课题背景及意义 1.2研究现状 1.3ssm框架介绍 1.3论文结构与章节安排 2 宠物领养系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 …

深入剖析:正则表达式的奥秘

简介 正则表达式(Regular Expressions)是一种强大的文本处理工具,一种用于匹配文本模式的字符串。它由特定的字符和操作符组成,用于定义一个搜索模式。这些搜索模式可以用于文本搜索、替换、验证和提取数据等多种用途。 以下是一…

火狐浏览器导入burpsuite CA 证书无法正常上网

当我们给火狐浏览器设置burpsuite代理,并给火狐导入了burpsuite的CA证书后,仍然无法上网的解决方法。 当我们把浏览器的代理配置好之后,浏览器导入证书,burpsuite设置好代理后,如上图,仍然无法上网&…

【后端开发】手写一个简单的线程池

半同步半异步线程池 半同步半异步线程池分为三层: 同步服务层 —— 处理来自上层的任务请求,将它们加入到排队层中等待处理。 同步排队层 —— 实际上是一个“同步队列”,允许多线程添加/取出任务,并保证线程安全。 异步服务层…