当前位置: 首页 > article >正文

链式队列:高效实现O(1)入队出队

引言在之前的文章中我们系统学习了栈结构顺序栈和链栈。栈是后进先出LIFO的结构而今天要讲解的队列Queue则是先进先出FIFOFirst In First Out的结构。队列在计算机科学中应用极为广泛操作系统的任务调度、消息队列、打印队列、网络数据包缓冲……几乎所有需要排队处理的场景都离不开队列。本文将详细讲解链式队列的完整实现。链式队列使用链表节点动态存储元素配合头尾指针实现 O(1) 的入队和出队操作。第一部分链式队列的设计原理一、核心数据结构链式队列由两个结构体组成// 1. 节点结构体 typedef struct Queuenode { ElempType val; // 数据域 struct Queuenode* next; // 指针域指向下一个节点 } Queuenode, *PQueuenode; // 2. 队列管理结构体带头结点 typedef struct LinkQueue { PQueuenode front; // 队头指针指向头结点 PQueuenode rear; // 队尾指针指向最后一个节点 } LinkQueue, *PLinkQueue;二、关键设计头结点 双指针三、队列状态判断状态frontrear条件空队列指向头结点指向头结点front rear有元素指向头结点指向最后一个节点front ! rear一个元素指向头结点指向唯一节点front-next rear已销毁NULLNULLfront NULL rear NULL四、为什么需要头结点和尾指针设计要素作用头结点统一空队列和非空队列的插入/删除操作避免判空特殊处理front 指针始终指向头结点方便出队操作O(1)rear 指针始终指向最后一个节点方便入队操作O(1)第二部分初始化与销毁一、创建节点PQueuenode buynode(ElempType val) { PQueuenode p (PQueuenode)malloc(sizeof(Queuenode)); if (p NULL) return NULL; p-next NULL; p-val val; return p; }二、初始化带头结点void InitLinkQueue(PLinkQueue ps) { assert(ps ! NULL); // 创建头结点 PQueuenode p buynode(0); if (p NULL) return; // 空队列front 和 rear 都指向头结点 ps-rear p; ps-front p; }初始化后的状态三、销毁void Destroy(PLinkQueue ps) { assert(ps ! NULL); if (Isempty(ps)) return; // 逐个释放所有节点包括头结点 while (ps-front ! NULL) { PQueuenode p ps-front; ps-front p-next; free(p); } // 指针置空 ps-rear NULL; }清空 vs 销毁// 清空保留头结点只释放数据节点 void Clear(PLinkQueue ps) { assert(ps ! NULL); if (Isempty(ps)) return; while (ps-front-next ! NULL) { PQueuenode p ps-front-next; ps-front-next p-next; free(p); } ps-rear ps-front; // rear 回到头结点 } // 销毁释放所有节点包括头结点 void Destroy(PLinkQueue ps) { // 释放所有节点指针置 NULL }操作头结点frontrear后续使用清空保留指向头结点指向头结点可继续使用销毁释放NULLNULL需重新初始化第三部分核心操作实现一、入队Pushbool Push(PLinkQueue ps, ElempType val) { assert(ps ! NULL); // 1. 创建新节点 PQueuenode p buynode(val); if (p NULL) return false; // 2. 插入到队尾 ps-rear-next p; // 当前最后一个节点的 next 指向新节点 ps-rear p; // rear 后移 return true; }入队过程图解入队的特殊情况// 空队列入队// 入队前front rear 头结点// 入队后front 头结点, rear 新节点// 代码逻辑完全适用无需特殊处理二、出队Popbool Pop(PLinkQueue ps, ElempType* pval) { assert(ps ! NULL pval ! NULL); if (Isempty(ps)) return false; // 1. 获取队头节点头结点后的第一个节点 PQueuenode p ps-front-next; // 2. 获取数据 *pval p-val; // 3. 跳过被删除的节点 ps-front-next p-next; // 4. 特殊处理如果删除的是最后一个节点rear 要回退 if (p ps-rear) { ps-rear ps-front; } // 5. 释放节点 free(p); return true; }注意原代码中缺少了rear回退的特殊处理。当队列只有一个元素时出队后rear应该指向头结点。修正后的代码bool Pop(PLinkQueue ps, ElempType* pval) { assert(ps ! NULL pval ! NULL); if (Isempty(ps)) return false; PQueuenode p ps-front-next; *pval p-val; ps-front-next p-next; // ★ 关键删除的是最后一个节点时更新 rear if (p ps-rear) { ps-rear ps-front; } free(p); return true; }三、获取队头和队尾// 获取队头元素 bool Getfront(PLinkQueue ps, ElempType* pval) { assert(ps ! NULL); if (Isempty(ps)) return false; *pval ps-front-next-val; // 头结点后的第一个节点 return true; } // 获取队尾元素 bool Getrear(PLinkQueue ps, ElempType* pval) { assert(ps ! NULL); if (Isempty(ps)) return false; *pval ps-rear-val; // 直接通过 rear 指针获取 return true; }四、判空bool Isempty(const PLinkQueue ps) { assert(ps ! NULL); return ps-front ps-rear; }五、获取元素个数int Getsize(const PLinkQueue ps) { assert(ps ! NULL); int n 0; for (Queuenode* p ps-front-next; p ! NULL; p p-next) { n; } return n; }注意这里的获取大小是 O(n) 遍历。如果想 O(1)可以在LinkQueue结构体中添加cursize成员。第四部分完整操作一览时间复杂度分析操作时间复杂度说明初始化O(1)创建头结点判空O(1)比较 front 和 rear入队 (Push)O(1)直接在 rear 后插入出队 (Pop)O(1)删除 front-next获取队头O(1)读取 front-next-val获取队尾O(1)读取 rear-val获取大小O(n)需要遍历可优化为 O(1)清空/销毁O(n)逐个释放节点操作要点速查第六部分链式队列 vs 顺序队列对比项链式队列顺序队列循环队列存储方式离散节点连续数组容量限制无内存足够即可有预分配或扩容入队/出队O(1)O(1)内存开销每节点多一个指针仅数据空间缓存友好差内存不连续好内存连续实现复杂度稍复杂需要处理循环下标适用场景元素数量不可预估元素数量可预估总结一、链式队列的核心原理二、操作复杂度速查操作时间复杂度关键步骤入队O(1)rear-next p; rear p;出队O(1)p front-next; front-next p-next; free(p);获取队头O(1)front-next-val获取队尾O(1)rear-val判空O(1)front rear三、一句话记忆链式队列用 front 和 rear 两个指针分别指向头结点和尾节点入队时在 rear 后面插入并更新 rear出队时删除 front 后面的节点实现 O(1) 的入队和出队操作。出队时如果删除了最后一个节点必须将 rear 回退到头结点。

相关文章:

链式队列:高效实现O(1)入队出队

引言在之前的文章中,我们系统学习了栈结构(顺序栈和链栈)。栈是"后进先出"(LIFO)的结构,而今天要讲解的队列(Queue)则是"先进先出"(FIFO&#xff0c…...

Pearcleaner终极指南:如何彻底清理Mac应用残留文件

Pearcleaner终极指南:如何彻底清理Mac应用残留文件 【免费下载链接】Pearcleaner A free, source-available and fair-code licensed mac app cleaner 项目地址: https://gitcode.com/gh_mirrors/pe/Pearcleaner 还在为Mac电脑存储空间不足而烦恼吗&#xff…...

Genshin_StarRail_fps_unlocker:终极帧率解锁指南,轻松突破60帧限制

Genshin_StarRail_fps_unlocker:终极帧率解锁指南,轻松突破60帧限制 【免费下载链接】Genshin_StarRail_fps_unlocker Genshin Impact & HKSR Fps Unlock 原神崩铁帧率解锁 项目地址: https://gitcode.com/gh_mirrors/ge/Genshin_StarRail_fps_unl…...

魔兽争霸3帧率解锁与界面修复终极指南:3步解决所有显示异常

魔兽争霸3帧率解锁与界面修复终极指南:3步解决所有显示异常 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸3的卡顿画面和界…...

基于MCP协议的本地化地址数据处理工具:sthan-mcp-server深度解析

1. 项目概述:一个面向开发者的地址数据处理工具集最近在折腾一些需要处理用户地址信息的项目,比如电商、物流或者用户注册表单,发现地址数据的标准化和验证真是个老大难问题。用户输入五花八门,“北京市海淀区中关村大街1号”可能…...

Geckodriver终极指南:快速安装Firefox自动化测试工具

Geckodriver终极指南:快速安装Firefox自动化测试工具 【免费下载链接】geckodriver WebDriver Classic proxy for automating Firefox through Marionette 项目地址: https://gitcode.com/gh_mirrors/ge/geckodriver Geckodriver是连接W3C WebDriver客户端与…...

别再满世界找grep了!Windows上PowerShell自带的Select-String和findstr,5分钟上手教程

Windows高效文本搜索指南:Select-String与findstr实战解析 每次在Windows环境下需要搜索文本时,你是否会下意识地怀念Linux中的grep命令?作为开发者或运维人员,快速定位日志、配置文件或代码片段是日常高频操作。实际上Windows平台…...

科新永安电子锁-酒店门锁-幽冥大陆(一百20)—东方仙盟

对接线路图针对这种主板对接主板门锁常见故障自助解决2声---正确提示,表示是设置卡3声---门锁已反锁,解决方法:用能开反锁的卡或解除反锁6声---房号不对,解决方法:设置门锁的房号7声---卡已过期,解决方法&a…...

从零构建私有化AI智能体中枢:Comobot部署、编排与生产实践

1. 项目概述:从零构建你的私有化智能体中枢如果你和我一样,对市面上的AI助手既爱又恨——爱其智能,恨其不可控、数据隐私的担忧以及无法深度融入自己的工作流——那么,Comobot这个项目或许能让你眼前一亮。它不是一个简单的聊天机…...

作为一名大二学生对于Vibe Coding的理解

🌈 个人主页: Hygge_Code 🔥 热门专栏:从0开始学习Java | Linux学习 | 计算机网络 💫 个人格言: “既然选择了远方,便不顾风雨兼程” 文章目录关于Vibe Coding前言什么是Vibe Coding(氛围感编程)? &#x…...

Brush 3D 重建引擎:多系统兼容、功能强大,渲染训练速度比 gsplat 更快!

特性训练方面,Brush 可接受 COLMAP 数据或 Nerfstudio 格式的数据集,在本地、移动端和浏览器中都能完全支持训练。训练时可与场景交互,实时查看训练动态,对比渲染效果与输入视图,还支持对带透明度的图像进行遮罩处理。…...

AI编程再突破:文心快码发布行业首个多模态、多智能体协同Comate AI IDE

前言 2025年6月23日(图灵诞辰日),百度在AI开放日正式发布文心快码Comate AI IDE,这是全球首个深度融合多模态感知与多智能体协同能力的独立AI原生开发环境。它彻底打破了传统AI编程工具"单线程补全、黑盒式生成"的局限&…...

SS928/SD3403边缘AI视觉芯片开发:从环境搭建到模型部署实战

1. 项目概述:解码新一代视觉处理核心最近在嵌入式视觉和边缘计算圈子里,SS928和SD3403这两个名字被提及的频率越来越高。很多刚接触的朋友可能会有点懵,这两个型号到底是什么关系,又能用来做什么?简单来说,…...

ESP32-CAM PSRAM与DinBase升级:解决内存瓶颈与供电稳定性

1. 项目概述:当ESP32-CAM遇上PSRAM与DinBase,我们能玩出什么新花样?最近在捣鼓物联网视觉项目时,发现了一个挺有意思的新玩意儿——ESP32CAM-PSRAM & DinBase。这名字听起来有点拗口,但拆开来看,其实就…...

如何评估你的 Agent 是否真的在思考

重新审视智能:如何用科学、工程与可量化标准评估你的 Agent 是否真的在思考 警告:全文约 12.7 万字,由 8 个核心章节组成,单节最低字数超过 1.1 万字。建议分段阅读,配合工具与项目实践,可获得最佳学习效果。 0. 章节导航与阅读建议 为了帮助不同背景的读者(从 AI 产品…...

初识Verilog

...

静态解算全流程详解——以华测 CGO 为例

应粉丝要求,以华测 CGO 软件为例,完整拆解 GNSS 静态解算从外业准备到成果输出的每一个环节。篇幅较长,建议先收藏再慢慢消化。 如果觉得有用,欢迎点赞、分享、转发,也特别感谢给我点赞赏的帅气粉丝!一、前…...

FVCOM-FABM耦合器实战:手把手教你配置ERSEM生态模型(附避坑指南)

FVCOM-FABM耦合器实战:手把手教你配置ERSEM生态模型(附避坑指南) 当海洋生态建模遇上高性能计算,FVCOM-FABM-ERSEM的组合正在成为水生生态系统模拟的黄金标准。这套工具链能够精确模拟从营养盐循环到浮游生物动态的复杂过程&#…...

Vivado里手把手配置MIPI CSI-2 RX Subsystem IP核:从D-PHY选IO到Video Format Bridge算位宽

Vivado中MIPI CSI-2 RX Subsystem IP核配置实战:从D-PHY选型到视频格式转换 在ZYNQ系列SoC的视觉处理系统中,MIPI CSI-2接口作为连接图像传感器的标准协议,其硬件实现往往成为项目成败的关键节点。本文将深入剖析Vivado工具中MIPI CSI-2 RX S…...

在GitHub项目中集成Taotoken多模型API的完整配置指南

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在GitHub项目中集成Taotoken多模型API的完整配置指南 将大模型能力集成到GitHub托管的项目中,是现代开发工作流的常见需…...

Tina Linux存储介质实战切换:从eMMC到SPI NAND的配置迁移与避坑指南

1. 为什么需要从eMMC迁移到SPI NAND? 在嵌入式系统开发中,存储介质的选择往往决定了产品的成本和性能表现。eMMC作为传统存储方案,具有容量大、读写速度快的特点,但随着芯片价格上涨和供应链波动,越来越多的开发者开始…...

Qt Creator远程调试实战:当你的开发机是Win10,测试机是Win7时该怎么办?

Qt Creator跨Windows版本远程调试实战:Win10到Win7的完整解决方案 当开发环境与测试环境存在Windows版本差异时,Qt项目的远程调试往往会遇到各种"玄学"问题。本文将针对Win10开发机与Win7测试机的典型组合,深入解析CDB远程调试的完…...

解密Ren‘Py游戏资源:掌握rpatool的5个核心应用场景

解密RenPy游戏资源:掌握rpatool的5个核心应用场景 【免费下载链接】rpatool (migrated to https://codeberg.org/shiz/rpatool) A tool to work with RenPy archives. 项目地址: https://gitcode.com/gh_mirrors/rp/rpatool 你是否曾经好奇过RenPy视觉小说游…...

告别第三方工具:手把手教你打造微软官方WinPE系统维护盘

1. 为什么你需要一个官方WinPE维护盘? 每次电脑系统崩溃时,你是不是也在各大论坛疯狂搜索"如何重装系统"?市面上确实有很多第三方PE工具,比如老毛桃、微PE之类的,用起来确实方便。但作为一个在IT行业摸爬滚…...

英文论文降AI全靠同义词替换?错!3款“结构级”辅助工具实测,稳过Turnitin

这两天帮朋友看海外项目的英文稿,发现大家全卡在了 Turnitin 的高疑似度上。熬夜手敲的长篇英文,一查AI率高的吓人,直接让人血压飙升。 为了提升文本表达的原创度,很多人疯狂寻找免费降ai率的方法。其实现在的海外检测早就进化了&…...

A15 工业路由器IP前缀高速检索与内存压缩系统

A15 工业路由器IP前缀高速检索与内存压缩系统 项目概述 本项目源自《计算机程序设计艺术》(TAOCP)算法库的知识的系统化工程落地。维度内容组合算法字典树(Trie) PATRICIA 树TAOCP出处卷3 6.3 (Trie) 卷3 6.3 (PATRICIA)难度★★…...

命令行状态监控新思路:打造你的智能手表终端看板

1. 项目概述:一个为命令行爱好者打造的“腕上终端”如果你和我一样,是个重度依赖命令行(CLI)工作的开发者、运维或者极客,那你一定有过这样的体验:眼睛紧盯着屏幕,手指在键盘上飞舞,…...

智能汽车纵向行车辅助分层控制【附程序】

✨ 长期致力于交通事故场景分析、智能跟车、自动紧急制动、分层控制、联合仿真测试研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)基于真实事故场景的…...

告别元路径!用HGT(异构图Transformer)处理学术图谱实战:从OAG数据到作者消歧

异构图Transformer实战:从OAG数据到作者消歧的完整解决方案 学术图谱中的作者消歧一直是知识图谱构建中的核心挑战。当两位学者姓名相同时,如何准确区分他们的研究成果?传统方法依赖人工设计的元路径和复杂规则,而HGT(…...

RDP Wrapper完整教程:Windows家庭版免费开启远程桌面多用户功能终极指南

RDP Wrapper完整教程:Windows家庭版免费开启远程桌面多用户功能终极指南 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap 还在为Windows家庭版无法使用远程桌面功能而烦恼吗?RDP Wrapper Lib…...