news 2026/5/8 16:19:48

数据结构学习篇(7)---队列

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据结构学习篇(7)---队列

1. 队列的概念及结构

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

  • 入队列:进行插入操作的一端称为队尾。
  • 出队列:进行删除操作的一端称为队头。

队列和栈是有所不同的,比如入栈顺序是1 2 3 4,但是出栈顺序可以有多种,不一定是 1 2 3 4,因为它可以边进边出,所以是一个一对多的关系;而队列的入队列顺序和出队列顺序是一样的,是一个一对一的关系,正是基于队列的这种性质,它可以用于保持公平性(例如做一个抽号机:比如吃饭排队拿取号码,先来的先拿,后来的后拿)。

也可以利用队列来做一个好友推荐(广度优先遍历)

假如要给小徐推荐好友,那么就以小徐为起点,首先让小徐进入队列,然后让小徐出队列(第一圈结束)的同时,让小徐的好友小明和小王入队列,这也就意味着当小徐出队列时,队列中剩下的都是小徐的朋友,然后按照顺序让小明出队列,出队列的同时让小明的朋友入队列,然后让小王出队列(第二圈结束),出队列的同时让小王的朋友入队列,这时小徐的朋友都出队列了,剩下的都是小徐朋友的朋友(也就是处于第三圈上的好友),这个时候就可以将队列中的好友推荐给小徐,不断循环这个步骤,就可以一步一步扩大好友圈。

2. 队列的功能实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。那么确定了使用链表,就要考虑是使用双向链表还是单向链表,因为双向链表肯定是可以实现队列功能的,但是我们优先考虑能不能使用单链表来实现,如果单链表能实现,就不使用双向链表,因为单向链表比双向链表更加节省空间。

2.1 一级指针还是二级指针

在数据结构的学习中,已经讨论过很多次到底是用一级指针还是二级指针的问题,我也混淆了很久,最简单的记忆方法就是去看你到底要不要去通过形参ppehad改变实参plist,若不不想改变实参,那形参就直接用一级指针接收即可,如果想要通过形参改变实参,那么就使用二级指针接收,因为只有对二级指针进行一次解引用,才能读取到实参部分,然后对*pphead的改变,就相当于是对plist的改变。

在队列的实现中,因为队列的本质是单链表,我在学习单链表的过程中,是使用二级指针来完成相应的功能的,在学习双向链表中,是使用一级指针来完成相应的功能的,这是因为在双向链表中引入了“头节点”,也就是“哨兵位”,因为指向哨兵位的指针plist是不需要被改变的,所以用一级指针接收即可,这一点我在双向链表的章节中也提到过;所以对于这节中的队列,为了避免二级指针的繁琐,也直接使用一级指针来接收,但是是使用一种新的方式来解决这个问题:直接将指向链表头节点和尾节点的指针封装成一个结构体,所以想要改变这两个指针,就相当于改变这个结构体,比如要改变实参int p,那形参就传int*p(也就是接收整型变量p的地址&p),要改变实参int* p,那就传int** pp(也就是接收指针p的地址),所以现在要改变实参结构体变量stuct Name p,那么形参就传struct Name* p(也就是接收结构体变量p的地址&p),这就转化为了只需要传一级指针,而不是二级指针。

typedef int QDataType; // 链式结构:表示队列 typedef struct QListNode { struct QListNode* next; QDataType val; }QNode; // 队列的结构 typedef struct Queue { QNode* phead; QNode* ptail; int size;//存入一个数据就计数一次,方便后面计数函数的实现,同时也降低了时间复杂度 }Queue; // 初始化队列 void QueueInit(Queue* pq); // 队尾入队列 void QueuePush(Queue* pq, QDataType x); // 队头出队列 void QueuePop(Queue* pq); // 获取队列头部元素 QDataType QueueFront(Queue* pq); // 获取队列队尾元素 QDataType QueueBack(Queue* pq); // 获取队列中有效元素个数 int QueueSize(Queue* pq); // 检测队列是否为空 bool QueueEmpty(Queue* pq); // 销毁队列 void QueueDestroy(Queue* pq);

这种方法既避免了传多个参数,又避免了传二级指针!

2.2 队列的初始化

代码实现:

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

2.3 入队列的实现

// 队尾入队列 void QueuePush(Queue* pq, QDataType x) { assert(pq); QNode* newnode = (QNode*)malloc(sizeof(QNode));//开辟动态空间 if (newnode == NULL) { perror("malloc fail"); return; } //进行初始化 newnode->val = x; newnode->next = NULL; //进行插入 if (pq->ptail == NULL) { pq->phead = pq->ptail = newnode; } else { pq->ptail->next = newnode; pq->ptail = newnode; } pq->size++; }

2.4 出队列的实现

// 队头出队列 void QueuePop(Queue* pq) { assert(pq); assert(pq->size != 0); //一个节点的情况 if (pq->phead ->next == NULL) { free(pq->phead);//free的是指针指向的节点,而不是释放指针,注意区别 pq->phead = pq->ptail = NULL; } //多个节点的情况 else { QNode* next = pq->phead->next; free(pq->phead); pq->phead = next; } pq->size--; }

注意:这里面的free函数释放的是指针所指向的节点的空间,也就是malloc动态开辟的内存空间,而不是指针pq->phead或者pq->ptail。

2.5 队列其他功能的实现

// 获取队列头部元素 QDataType QueueFront(Queue* pq) { assert(pq); assert(pq->phead);//头节点如果为NULL,说明没有节点存入,那读取就没有意义了 return pq->phead->val; } // 获取队列队尾元素 QDataType QueueBack(Queue* pq) { assert(pq); assert(pq->ptail);//尾节点如果为NULL,说明没有节点存入,那读取就没有意义了 return pq->ptail->val; } // 获取队列中有效元素个数 int QueueSize(Queue* pq) { assert(pq); return pq->size; } // 检测队列是否为空 bool QueueEmpty(Queue* pq) { asswet(pq); return pq->size == 0; } // 销毁队列 void QueueDestroy(Queue* pq) { assert(pq); QNode* pcur = pq->phead; while (pcur) { QNode* next = pcur->next; free(pcur); pcur = next; } pq->phead = pq->ptail = NULL; pq->size=0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 13:05:34

网盘直链助手:解锁免客户端高速下载新体验

网盘直链助手是一款免费开源的专业下载工具,专门解决网盘限速和客户端依赖问题。通过智能解析六大主流网盘API接口,将受限制的网盘链接转换为真实下载地址,配合多线程下载工具实现满速下载,无需安装任何网盘官方应用。 【免费下载…

作者头像 李华
网站建设 2026/4/18 5:07:16

【Open-AutoGLM部署终极指南】:从零到生产环境全流程实战揭秘

第一章:Open-AutoGLM部署概述Open-AutoGLM 是一个开源的自动化通用语言模型推理框架,专为高效部署和管理大规模语言模型而设计。它支持多种后端引擎、动态批处理、模型量化与多设备调度,适用于企业级AI服务场景。该框架通过标准化接口封装底层…

作者头像 李华
网站建设 2026/4/18 10:20:05

AdGuard Home终极配置教程:百万规则打造纯净网络环境

AdGuard Home终极配置教程:百万规则打造纯净网络环境 【免费下载链接】AdGuardHomeRules 高达百万级规则!由我原创&整理的 AdGuardHomeRules ADH广告拦截过滤规则!打造全网最强最全规则集 项目地址: https://gitcode.com/gh_mirrors/ad…

作者头像 李华
网站建设 2026/4/17 14:48:46

Boss直聘批量投递终极指南:5分钟完成50+岗位精准投递

Boss直聘批量投递终极指南:5分钟完成50岗位精准投递 【免费下载链接】boss_batch_push Boss直聘批量投简历,解放双手 项目地址: https://gitcode.com/gh_mirrors/bo/boss_batch_push 还在为海量岗位筛选而烦恼吗?Boss直聘批量投递工具…

作者头像 李华
网站建设 2026/5/3 8:44:54

线性与Softmax回归的实现与应用

线性与Softmax回归的实现与应用 本系列课程从基础理论到实践应用,全面覆盖线性回归和softmax回归的实现,包括模型构建、参数优化、数据处理及使用深度学习框架进行高效开发。 线性回归原理与实践线性回归模型实践深度学习框架下的线性回归模型快速构建…

作者头像 李华