一篇读懂队列(Queue)————手撕队列,图文并茂+代码逐行精讲
前言队列Queue是我们日常生活中再熟悉不过的概念——排队买奶茶、银行叫号、打印机任务调度背后都是队列的思想。在计算机世界队列更是操作系统进程调度、消息队列、BFS 算法的基石。本文会从零开始手写一个完整的链式队列C语言实现并逐段拆解代码的设计思路让你不仅会用更懂为什么这么写。如果你正在学数据结构或者准备面试这篇文章值得你花 15 分钟认真读完。一、什么是队列——先进先出FIFO1.1概念队列只允许在一端进行数据操作在另一端进行删除数据操作的特殊线性表队列具有先进先出的规则。我们不难发现队列的逻辑结构是线性的但是物理结构不一定是线性的。入队列进行插入操作的一端称为队尾。出队列进行删除操作的一端称为队头1.2为什么用链表实现队列队列有两种常见实现方式实现方式入队出队数组顺序队列O(1)O(n)(需移动元素链表链式队列O(1)O(1)如果用数组的话出队时头元素删除后后面的元素要整体前移效率低下。而链表只需改变指针时间复杂度O1所以实际工程中链式队列更常用。二、队列的接口设计(Queue.h中进行声明)在执行操作之前我们依然是需要先创建三个文件分别是Queue.h、Queue.c、test.c。三、结构体定义1.每个节点是独立的堆内存通过 next 指针串联起来不需要连续空间支持动态扩容2.用 typedef 重命名数据类型后续想存char、结构体都能一键修改复用性强为什么需要单独定义一个Queue结构体因为队列需要同时维护头和尾两个指针把它们封装在一起函数传参更清晰也更方便管理。如果只用一个头指针每次入队都要遍历到尾时间复杂度编程O(n)失去了链表的优势。四、代码逐段精讲Queue.c中实现4.1初始化——QueueInit1.assert(pq) 防御式编程防止外面传NULL空指针进来导致后续 pq-phead 非法访问崩溃2.把头尾指针都置为 NULL 代表当前队列为空没有任何节点3.初始化只操作指针不创建节点节点只有在入队时才动态开辟4.2判空——QueueEmpty1.空队列的标志就是 phead NULL 直接返回表达式结果即可代码最简洁2.返回值用 bool 类型语义清晰后续出队、取数据的断言都可以直接复用这个函数4.3入队——队尾插入QueuePush1.先创建节点再接入 malloc 开辟内存后必须检查是否失败内存不足时 malloc 会返回NULL不判断会造成野指针崩溃。2.新节点 next 必须手动置空 malloc 出来的内存是随机垃圾值不置空的话后续遍历会越界。3.为什么要分空队列和非空队列1空队列时头尾指针都指向NULL新节点是第一个节点必须同时给 phead 和 ptail 赋值2非空队列时只需要操作尾指针头指针保持不动4. 两步操作不能反必须先把新节点接在原尾节点后面再移动尾指针否则原尾节点地址会丢失链表就断了。4.4出队——队头删除QueuePop1. assert(!QueueEmpty(pq)) 空队列不能出队属于非法操作直接断言拦截2. 为什么要单独处理「只剩一个节点」的情况当队列只有一个节点时 phead 和 ptail 指向同一个节点。如果只释放 phead 、只移动 phead ptail 就会变成悬空指针野指针指向已经被释放的内存后续入队会崩溃。所以这种情况必须同时把两个指针都置空。3. 多个节点的场景先保存下一个节点地址再释放头节点最后头指针后移。顺序不能乱否则free后头节点没了就找不到下一个节点了。4.5取队头数据——QueueFront1. 只读操作不修改队列结构直接返回头节点的 data 即可2. 必须断言非空空队列没有数据访问 phead-data 属于空指针解引用直接崩溃4.6取队尾数据——QueueBack1. 只读操作不修改队列结构直接返回尾节点的 data 即可2. 必须断言非空空队列没有数据访问 ptail-data 属于空指针解引用直接崩溃4.7取队列有效元素个数——QueueSize1. 同样用临时指针遍历计数不改动原队列2. 时间复杂度O(N)需要遍历整条链表3. 拓展优化如果想O(1)获取长度可以在 Queue 结构体里加一个 size 成员入队1、出队-1用一点点空间换时间。如下图这样修改即可4.8打印队列——QueuePrint1. 先判空空队列直接提示并返回避免无效遍历2. 绝对不能直接移动 phead 遍历如果让 phead 自己往后走遍历完头指针就丢了整个队列都找不到了。所以用临时指针 pcur 拷贝头节点地址只动临时变量原队列结构丝毫不改。3. 终止条件 pcur NULL 代表已经遍历完最后一个节点4.9销毁队列——QueueDestory1. 为什么要先保存 next 再free节点被free之后它的内存就被回收了再去访问 pcur-next 是非法的。所以必须在释放当前节点前先把下一个节点的地址存下来。2. 遍历释放完所有节点后一定要把头尾指针置空避免变成野指针并把size归零3. 销毁只释放链表节点队列结构体本身是外面定义的不需要我们free五、可执行代码验证test.c中实现六、总结1. 链式队列核心是单链表 头尾双指针保证入队、出队都是O(1)时间复杂度2. 所有只读操作打印、计数都要用临时指针遍历绝对不能改动原头尾指针3. 边界场景一定要单独处理空队列入队、只剩一个节点出队是最容易出野指针的地方4. 动态开辟的节点一定要记得销毁防止内存泄漏

相关新闻

Linux命令攻略

Linux命令攻略

Linux命令攻略![图片](https://i-blog.csdnimg.cn/img_convert/00db6ec727ceec6e0536c1337aba5f29.jpeg

2026/7/23 1:21:30 阅读更多 →
超全 CentOS7 实操教程:man 帮助手册、Vim 全套快捷键、IO 管道重定向详解

超全 CentOS7 实操教程:man 帮助手册、Vim 全套快捷键、IO 管道重定向详解

Linux运维必备:帮助手册、Vim编辑器、IO重定向完整实操教程 前言 在日常服务器运维工作中,我们经常需要查阅命令文档、修改配置文件、处理命令输出日志。本文完整拆解三大高频核心技能:man帮助手册全套用法、Vim编辑器全量操作、标准输入输出…

2026/7/23 10:16:12 阅读更多 →
Linux 内核 LSM 安全模块在嵌入式中的应用:SELinux 最小权限策略的裁剪与定制方法

Linux 内核 LSM 安全模块在嵌入式中的应用:SELinux 最小权限策略的裁剪与定制方法

Linux 内核 LSM 安全模块在嵌入式中的应用:SELinux 最小权限策略的裁剪与定制方法 一、嵌入式 Linux 系统的权限管理困境:root 即上帝的时代必须终结 长期以来,嵌入式 Linux 设备普遍以 root 权限运行所有进程,原因是"嵌入式…

2026/7/21 16:41:33 阅读更多 →

最新新闻

Unity地形旋转全攻略:一键处理高度图、纹理与植被数据同步

Unity地形旋转全攻略:一键处理高度图、纹理与植被数据同步

1. 项目概述:为什么我们需要旋转整个Terrain?在Unity3D的地形编辑和场景搭建中,我们经常会遇到一个看似简单却异常棘手的需求:将整个Terrain地形,连同它上面生长的树木、铺设的贴图、散布的细节草和岩石,一…

2026/7/24 6:23:05 阅读更多 →
多模态问答技术解析与应用实践

多模态问答技术解析与应用实践

1. 多模态模型问答技术解析上周在调试一个客户项目时,遇到个典型场景:用户上传的产品图片需要自动生成规格说明。传统单模态方案要么用CV识别物体,再用NLP生成文本,流程割裂导致信息丢失严重。这让我重新审视了多模态问答技术的价…

2026/7/24 6:23:05 阅读更多 →
基于YOLOv10的实时火焰检测系统设计与实现

基于YOLOv10的实时火焰检测系统设计与实现

1. 项目概述这个基于YOLOv10的火焰检测系统是我最近完成的一个计算机视觉项目,它能够通过摄像头、视频文件或静态图像实时检测火焰和火灾。作为一名长期从事目标检测开发的工程师,我发现现有的火焰检测方案要么精度不足,要么速度太慢&#xf…

2026/7/24 6:23:05 阅读更多 →
大语言模型系统指令设计原理与工程实践

大语言模型系统指令设计原理与工程实践

1. 系统指令(System Prompt)的本质解析在AI交互领域,系统指令(System Prompt)是对话初始阶段植入的"基因代码",它从根本上定义了AI助手的身份定位和行为范式。不同于用户直接输入的操作指令(User Prompt),系统指令更像是在对话开始…

2026/7/24 6:23:05 阅读更多 →
深度学习在音乐生成与编曲自动化中的应用实践

深度学习在音乐生成与编曲自动化中的应用实践

1. 项目概述作为一名长期从事音乐科技开发的工程师,我最近完成了一个融合深度学习与音乐处理的综合项目。这个系统能够实现从旋律生成到完整编曲的全流程自动化处理,同时集成了多种音乐格式的转换功能。在实际应用中,这套工具已经帮助独立音乐…

2026/7/24 6:23:05 阅读更多 →
深度学习神经网络调参实战技巧与优化策略

深度学习神经网络调参实战技巧与优化策略

1. 神经网络调参实战指南在深度学习项目中,调参往往是最耗时却又最关键的一环。我见过太多团队在数据准备和模型架构上花费大量精力,最后却因为调参不当导致前功尽弃。今天分享的这套调参方法论,是我从50多个实际项目中总结出的实战经验&…

2026/7/24 6:22:05 阅读更多 →

日新闻

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化,核心特色:三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;散点使用径向渐变实现立体 3D 圆球质感;支持鼠标 / 触屏拖拽画布,…

2026/7/24 0:00:29 阅读更多 →
AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口 AppCertDlls 位于 HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls。本文的程序功能是只读列出这个键在 64 位和 32 位注册表视图中的全部值,并显示每条值的来源、名称、类型和可安全显示的数…

2026/7/24 0:00:29 阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:29 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 3:59:20 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 1:23:39 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻