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

数据结构-队列(顺序存储、链式存储、双端队列)

队列是算法和开发中最常用的线性结构之一无论是操作系统任务调度、网络请求缓冲、算法滑动窗口还是消息队列中间件底层核心都是队列。一、队列1.1 什么是队列队列是一种受限的线性表严格遵循FIFO先进先出就像我们日常排队先排队的人先办理业务后排队的人后办理。1.2 两大核心端点队头 front负责出队删除元素队尾 rear负责入队插入元素规则只允许尾进、头出不允许中间插入、删除、修改1.3 队列的分类顺序存储队列数组实现普通顺序队列、循环顺序队列链式存储队列链表实现双端队列两端可进可出二、顺序存储队列数组实现顺序队列本质是连续数组存储数据通过 front、rear 下标指针控制出入队所有操作固定围绕两个指针移动实现。2.1 普通顺序队列底层原理front指向当前队头元素下标rear指向下一个可以入队的空位置入队rear 向后移动出队front 向后移动致命缺陷假溢出当数组前面元素出队后前端空间空置但 rear 走到数组末尾系统判定队列已满无法继续入队。有空位却无法存数据就是假溢出因此工程中几乎不用。结构体定义#includestdio.h#defineMaxSize5// 顺序队列结构体数组存储数据双指针typedefstruct{intdata[MaxSize];// 固定大小数组存储队列元素intfront;// 队头指针出队用intrear;// 队尾指针入队用}SqQueue;操作队列初始化核心逻辑队列创建后头尾指针全部归零代表空队列。voidInitQueue(SqQueue*q){q-front0;q-rear0;}判空操作核心逻辑头尾指针重合说明没有任何元素。intisEmpty(SqQueue*q){returnq-frontq-rear;}判满操作核心逻辑队尾指针走到数组最大长度代表数组无剩余空间。intisFull(SqQueue*q){returnq-rearMaxSize;}入队操作尾插核心逻辑先判断队列是否满未满则存入数据再向后移动队尾指针。intEnQueue(SqQueue*q,intx){if(isFull(q))return0;// 队列满入队失败q-data[q-rear]x;// 存入元素rear后移return1;// 入队成功}出队操作头删核心逻辑先判断队列是否空非空则取出队头元素再向后移动队头指针。intDeQueue(SqQueue*q,int*x){if(isEmpty(q))return0;// 队列空出队失败*xq-data[q-front];// 取出队头元素front后移return1;// 出队成功}优缺点总结优点结构简单、内存连续、访问速度快缺点存在假溢出、空间利用率极低、容量固定2.2 循环顺序队列通过逻辑环形数组取模运算解决假溢出问题是工程最常用的顺序队列。主动牺牲一个空间区分队空、队满状态。核心判定公式队空front rear队满(rear 1) % MaxSize front元素个数(rear - front MaxSize) % MaxSize结构体定义#includestdio.h#defineMaxSize5typedefstruct{intdata[MaxSize];intfront;intrear;}SqQueue;操作初始化队列逻辑头尾指针归0初始为空队列。voidInitQueue(SqQueue*q){q-frontq-rear0;}判空intisEmpty(SqQueue*q){returnq-frontq-rear;}判满逻辑利用取模实现环形判定避免首尾指针混淆。intisFull(SqQueue*q){return(q-rear1)%MaxSizeq-front;}循环入队逻辑先存值再通过取模移动 rear 指针到达数组末尾自动跳转头部。intEnQueue(SqQueue*q,intx){if(isFull(q))return0;// 队满直接失败q-data[q-rear]x;// 存入当前队尾位置q-rear(q-rear1)%MaxSize;// 循环后移return1;}循环出队逻辑先取出队头值再取模移动 front 指针实现环形出队。intDeQueue(SqQueue*q,int*x){if(isEmpty(q))return0;// 队空直接失败*xq-data[q-front];// 取出队头元素q-front(q-front1)%MaxSize;// 循环后移return1;}获取队列有效长度逻辑加 MaxSize 避免负数取模保证环形计算准确。intgetLength(SqQueue*q){return(q-rear-q-frontMaxSize)%MaxSize;}优缺点总结优点彻底解决假溢出、内存利用率高、读写速度快缺点容量固定无法动态扩容适合数据量稳定的场景三、链式存储队列链表实现链式队列基于单链表实现无固定容量动态扩容。采用带头结点设计规避空队列边界问题核心尾插入队、头删出队。结构体定义#includestdio.h#includestdlib.h// 链表节点结构typedefstructLNode{intdata;// 节点数据structLNode*next;// 后继指针}LNode;// 链式队列结构头尾双指针typedefstruct{LNode*front;LNode*rear;}LinkQueue;操作初始化队列逻辑创建头结点头尾指针同时指向头结点初始队列为空。voidInitQueue(LinkQueue*q){// 动态开辟头结点空间q-frontq-rear(LNode*)malloc(sizeof(LNode));q-front-nextNULL;// 头结点后继置空}判空逻辑头尾指针重合代表无有效元素。intisEmpty(LinkQueue*q){returnq-frontq-rear;}入队尾插法逻辑新建节点→挂载到队尾→更新尾指针全程不改动头指针。intEnQueue(LinkQueue*q,intx){// 1. 新建节点LNode*s(LNode*)malloc(sizeof(LNode));s-datax;s-nextNULL;// 2. 挂载到队尾q-rear-nexts;// 3. 尾指针后移q-rears;return1;}出队头删法逻辑取出首元素→断链释放节点→判断是否为最后一个节点重置尾指针避免野指针。intDeQueue(LinkQueue*q,int*x){if(isEmpty(q))return0;// 1. 指向第一个有效节点LNode*pq-front-next;*xp-data;// 2. 头结点指向新后继删除原队头q-front-nextp-next;// 3. 关键删除最后一个节点重置尾指针if(q-rearp){q-rearq-front;}free(p);// 释放内存防止内存泄漏return1;}优缺点与适用场景优点动态扩容、无溢出、不浪费内存无需提前开辟空间缺点每个节点存储指针有额外内存开销不支持随机访问读写速度略慢于顺序队列适用场景数据量不确定、频繁增减元素的场景四、双端队列Deque双端队列支持头尾双向入队、双向出队兼容普通队列和栈的所有功能基于循环数组实现沿用环形取模逻辑。结构体定义#includestdio.h#defineMaxSize5typedefstruct{intdata[MaxSize];intfront;intrear;}Deque;操作初始化voidInitDeque(Deque*d){d-frontd-rear0;}判空、判满intisEmpty(Deque*d){returnd-frontd-rear;}intisFull(Deque*d){return(d-rear1)%MaxSized-front;}队头入队反向入队逻辑front 指针先向前循环移动再存入数据实现头部插入。intEnFront(Deque*d,intx){if(isFull(d))return0;// 向前移动MaxSize 防止下标为负d-front(d-front-1MaxSize)%MaxSize;d-data[d-front]x;return1;}队尾入队常规入队intEnRear(Deque*d,intx){if(isFull(d))return0;d-data[d-rear]x;d-rear(d-rear1)%MaxSize;return1;}队头出队常规出队intDeFront(Deque*d,int*x){if(isEmpty(d))return0;*xd-data[d-front];d-front(d-front1)%MaxSize;return1;}队尾出队反向出队逻辑rear 指针先向前循环回撤再取出尾部数据。intDeRear(Deque*d,int*x){if(isEmpty(d))return0;// 尾部指针回撤d-rear(d-rear-1MaxSize)%MaxSize;*xd-data[d-rear];return1;}核心应用场景算法滑动窗口最大值、单调队列问题工程浏览器前进后退、历史记录管理缓存机制、任务双向调度五、四种队列全方位对比队列类型存储结构容量特性溢出问题核心特点适用场景普通顺序队列数组固定假溢出严重结构简单缺陷明显仅教学演示循环顺序队列数组固定无溢出速度最快、利用率高固定大小缓冲区链式队列链表动态无溢出动态扩容、无空间浪费数据量不确定场景双端队列数组/链表可选无溢出两端进出、功能最全算法刷题、双向调度
http://www.gsyq.cn/news/1373077.html

相关文章:

  • 【AgenticCPS】普通人怎么靠 618 赚返利?一套 CPS 实操打法
  • 在命令行中运行.py文件报错No module named triton
  • 用Python+GM(1,1)模型预测业务恢复时间:以航空业为例,手把手教你做灰色预测
  • C++ 字符串快速指南
  • 超级IP智能体 一键追爆口播短视频IP热门复刻同款视频程序一键矩阵发布
  • 人体姿态检测数据集分享(适用于YOLO系列深度学习检测任务)
  • 2026年Q2四川消防维修维保品牌名录及选型指南:成都消防维修口碑/消防技术服务/消防改造公司/消防改造多少钱/选择指南 - 优质品牌商家
  • Armv9-A加密点缓存维护机制与SoC优化实践
  • SVN SSL证书验证失败的根源与四关卡排障法
  • AI 术语通俗词典:RAG
  • 智能控制 第六章——集成智能控制系统
  • 多无人机协同通信-计算
  • 从原理到代码:用Python仿真TOA、TDOA和RSS定位算法(附GitHub源码)
  • 保姆级教程:在AirSim中用Python实现四旋翼的实时避障(附完整代码与避坑点)
  • Wireshark与FTK Imager电子证据采集实战指南
  • 破解‘特质波动率之谜’?用Python回测A股创业板数据,看看风险与收益到底啥关系
  • 2026桥梁防撞护栏优质产品推荐榜:桥梁河道景观护栏、河道景观桥梁护栏、河道桥梁防撞护栏、灯光桥梁护栏、防撞道路护栏选择指南 - 优质品牌商家
  • @Transactional 为什么能生效?一次 Debug 看懂 Spring 如何偷偷加事务
  • How to download Messenger chat history?(下载Messenger聊天记录)
  • 别再纠结PCA和t-SNE了!用Python实战对比,手把手教你选对降维方法(附代码避坑)
  • OpenAI 推出的 GPT-5.5 大模型,倒逼接口芯片升级迭代@ACP#IX7024应用迭代
  • 【AI问答/前端】现代前端的满天过海局(二)
  • Android 全栈体系 150 讲 - 49 深度完整版 Android 常用设计模式 + 架构模式 源码剖析、业务落地、面试精讲
  • 成都钢管供应商、2026规格齐全按需定制拿货 - 四川盛世钢联营销中心
  • 基于模糊控制算法的水位控制研究(Matlab代码实现)
  • 基于Simulink的四开关buck-boost变换器闭环仿真模型
  • FPG平台:行业前景下的战略定位评估
  • Java应用与前景
  • 核心经营指标优秀的旅游类上市公司有哪些? - 品牌2025
  • 旅游行业有哪些值得关注的上市公司,可从哪些维度筛选这类公司? - 品牌2025