首页/新闻资讯/正文详情

队列:一种让你又爱又恨的数据结构

发布时间:2026/9/26 4:05:36 来源:云帆数科 栏目:资讯中心
队列:一种让你又爱又恨的数据结构
队列Queue是一种与栈并列的基础线性数据结构。它的核心特点是先进先出也就是 First In First Out简称FIFO。你可以把队列想象成排队买票先来的人先买到票后来的人排在队尾。队列只允许在一端插入元素在另一端删除元素。允许插入的一端叫队尾rear允许删除的一端叫队头front。队列的常见操作有enqueue入队在队尾插入元素dequeue出队删除并返回队头元素front / peek查看队头元素但不删除isEmpty判断队列是否为空isFull判断队列是否已满主要用于顺序队列destroy销毁队列释放内存队列的应用非常广泛例如操作系统中的进程调度打印机任务队列消息队列广度优先搜索BFS键盘缓冲区网络数据包排队下面用 C 语言分别实现循环队列和链队列并给出一个经典应用用队列打印杨辉三角。一、循环队列的 C 语言实现如果用普通数组实现队列随着不断入队和出队front 和 rear 会不断后移最终导致“假溢出”数组前面明明有空位但 rear 已经到达末尾无法再入队。解决方法是使用循环队列把数组看作一个环当 rear 到达末尾时再回到下标 0。循环队列通常有两种设计牺牲一个存储单元用(rear 1) % MAX_SIZE front判断队满。增加一个size变量记录元素个数这样不会浪费空间逻辑也更直观。这里采用第二种方式。约定front指向队头元素rear指向队尾元素的下一个位置size记录当前元素个数空队列size 0满队列size MAX_SIZE入队data[rear] value; rear (rear 1) % MAX_SIZE; size出队*value data[front]; front (front 1) % MAX_SIZE; size--#include stdio.h #include stdlib.h #define MAX_SIZE 100 /* 循环队列 */ typedef struct { int data[MAX_SIZE]; int front; /* 队头下标 */ int rear; /* 队尾下一个位置 */ int size; /* 当前元素个数 */ } CircularQueue; /* 初始化队列 */ void initCircularQueue(CircularQueue *q) { q-front 0; q-rear 0; q-size 0; } /* 判断队列是否为空 */ int circularQueueEmpty(const CircularQueue *q) { return q-size 0; } /* 判断队列是否已满 */ int circularQueueFull(const CircularQueue *q) { return q-size MAX_SIZE; } /* 入队成功返回 1失败返回 0 */ int circularQueueEnqueue(CircularQueue *q, int value) { if (circularQueueFull(q)) { return 0; } q-data[q-rear] value; q-rear (q-rear 1) % MAX_SIZE; q-size; return 1; } /* 出队成功返回 1并把值存入 *value失败返回 0 */ int circularQueueDequeue(CircularQueue *q, int *value) { if (circularQueueEmpty(q)) { return 0; } *value q-data[q-front]; q-front (q-front 1) % MAX_SIZE; q-size--; return 1; } /* 查看队头元素成功返回 1失败返回 0 */ int circularQueuePeek(const CircularQueue *q, int *value) { if (circularQueueEmpty(q)) { return 0; } *value q-data[q-front]; return 1; }循环队列的优点是内存连续、访问效率高并且通过取模运算解决了假溢出问题。缺点是容量固定需要预先估计最大元素数量。二、链队列的 C 语言实现链队列用单链表实现。为了操作方便通常让front指向队头节点rear指向队尾节点。空队列front NULL且rear NULL入队创建新节点接到rear后面并更新rear出队删除front节点并更新front如果删除后队列为空还要把rear置为NULL链队列不需要预先指定容量因此一般不会出现“队满”的问题除非内存分配失败。/* 链队列 */ typedef struct QueueNode { int data; struct QueueNode *next; } QueueNode; typedef struct { QueueNode *front; /* 队头指针 */ QueueNode *rear; /* 队尾指针 */ } LinkQueue; /* 初始化链队列 */ void initLinkQueue(LinkQueue *q) { q-front NULL; q-rear NULL; } /* 判断链队列是否为空 */ int linkQueueEmpty(const LinkQueue *q) { return q-front NULL; } /* 入队 */ int linkQueueEnqueue(LinkQueue *q, int value) { QueueNode *node (QueueNode *)malloc(sizeof(QueueNode)); if (node NULL) { return 0; } node-data value; node-next NULL; if (q-rear NULL) { /* 空队列 */ q-front node; q-rear node; } else { q-rear-next node; q-rear node; } return 1; } /* 出队 */ int linkQueueDequeue(LinkQueue *q, int *value) { if (linkQueueEmpty(q)) { return 0; } QueueNode *tmp q-front; *value tmp-data; q-front tmp-next; if (q-front NULL) { /* 队列已空rear 也要置空 */ q-rear NULL; } free(tmp); return 1; } /* 查看队头元素 */ int linkQueuePeek(const LinkQueue *q, int *value) { if (linkQueueEmpty(q)) { return 0; } *value q-front-data; return 1; } /* 销毁链队列 */ void destroyLinkQueue(LinkQueue *q) { int value; while (linkQueueDequeue(q, value)) { /* 不断出队直到队列为空 */ } }链队列的优点是动态扩容、没有固定容量限制。缺点是每个节点需要额外的指针空间内存分配也可能带来一定开销。三、经典应用用队列打印杨辉三角杨辉三角是队列的经典应用之一。它的每一行都可以由上一行推导出来每个数等于上一行相邻两个数之和首尾都是 1。使用队列的算法思路初始化队列把第一行的1入队。对于每一行先在队尾入队一个0作为行结束标记。维护变量prev表示上一行前一个元素初始为0。循环出队如果出队元素是0说明本行结束把prev入队即下一行最后一个1换行结束本行。否则输出该元素把prev 当前元素入队并更新prev 当前元素。/* 用队列打印杨辉三角 */ void printYanghui(int n) { CircularQueue q; initCircularQueue(q); /* 第一行 */ circularQueueEnqueue(q, 1); for (int i 1; i n; i) { /* 入队 0 作为行结束标记 */ circularQueueEnqueue(q, 0); int prev 0; while (1) { int cur; circularQueueDequeue(q, cur); if (cur 0) { /* 本行结束入队下一行最后一个 1 */ circularQueueEnqueue(q, prev); printf(\n); break; } printf(%d , cur); circularQueueEnqueue(q, prev cur); prev cur; } } }测试printYanghui(5)输出1 1 1 1 2 1 1 3 3 1 1 4 6 4 1四、完整测试代码把前面的代码按顺序放在同一个.c文件中再添加上main函数即可运行。int main(void) { printf( 循环队列测试 \n); CircularQueue cq; initCircularQueue(cq); for (int i 1; i 5; i) { circularQueueEnqueue(cq, i * 10); } int value; while (circularQueueDequeue(cq, value)) { printf(%d , value); } printf(\n); printf( 链队列测试 \n); LinkQueue lq; initLinkQueue(lq); for (int i 1; i 5; i) { linkQueueEnqueue(lq, i * 10); } while (linkQueueDequeue(lq, value)) { printf(%d , value); } printf(\n); destroyLinkQueue(lq); printf( 杨辉三角测试 \n); printYanghui(6); return 0; }运行结果类似 循环队列测试 10 20 30 40 50 链队列测试 10 20 30 40 50 杨辉三角测试 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1五、循环队列与链队列对比对比项循环队列链队列存储方式数组单链表容量固定可能队满动态一般不会满入队出队复杂度O(1)O(1)内存开销较小连续内存每个节点多一个指针实现难度需要处理取模和队满稍复杂需管理内存适用场景元素数量可预估元素数量变化大六、总结队列是一种典型的“先进先出”结构核心操作都围绕队头和队尾进行。它的实现方式主要有两种循环队列用数组实现通过取模运算形成环解决假溢出问题简单高效但容量固定。链队列用链表实现动态灵活不需要预先指定容量但需要额外指针开销。队列虽然结构简单但在算法和工程中非常常见。进程调度、消息队列、广度优先搜索、缓冲区管理等都离不开队列。如果你正在学习数据结构建议亲手把上面的代码敲一遍再尝试实现用两个栈实现一个队列用两个队列实现一个栈用队列实现二叉树的层次遍历用循环队列模拟生产者—消费者问题用队列求解迷宫最短路径这些练习会让你对队列的理解更加深入。动手敲一遍比看十遍都管用。

相关推荐

ZCode:面向Agent时代的本地化统一运行时
ZCode:面向Agent时代的本地化统一运行时

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 4:05:30

后端工程师进阶指南:收藏!从0到1掌握AI工程核心思维与实践
后端工程师进阶指南:收藏!从0到1掌握AI工程核心思维与实践

本文针对后端工程师在AI浪潮中的焦虑,提出通过“心智模型重置”和“技术栈映射”来应对。文章结合Chip Huyen的《AI Engineering》和Valliappa Lakshmanan与Hannes Hapke的《Generative AI Design Patterns》,通过三个实战案例,阐述了如何从传… · 2026/9/26 4:05:30

2026年程序员薪资分化严重!收藏这份金字塔图,小白也能找到高薪赛道!
2026年程序员薪资分化严重!收藏这份金字塔图,小白也能找到高薪赛道!

本文通过猎聘《中国AI大模型人才报告2026》等数据,揭示了2026年程序员薪资的巨大分化,从头部AI科学家年薪200万到普通程序员月薪腰斩的现象。文章分析了薪资金字塔的层级结构,包括AI科学家、大模型算法工程师、AI智能体开发等高薪层级&#x… · 2026/9/26 4:05:30

嵌入式量产烧录版本管理:从命名规范到ERP/MES对接的完整实践
嵌入式量产烧录版本管理:从命名规范到ERP/MES对接的完整实践

1. 烧录版本管理为什么是量产环节的"隐形炸弹" 做嵌入式这行的朋友,估计都有过这种经历:实验室里跑得好好的板子,一到产线批量烧录就开始出幺蛾子。有的板子功能正常但就是连不上服务器,有的设备行为诡异像是跑了个&quo… · 2026/9/26 8:45:12

SCA凸优化实战:非凸问题迭代逼近与MATLAB代码解析
SCA凸优化实战:非凸问题迭代逼近与MATLAB代码解析

简介:一份专注SCA(Sequential Convex Approximation)凸优化算法的MATLAB实现资源包,面向需要处理非凸优化问题的学习者、研究者与工程技术人员,适用于无线通信、信号处理、能源系统等典型应用场景。压缩包内共2个文件&… · 2026/9/26 8:45:06

从水凝胶柔性传感器写到毕业论文:AI 写作工具到底怎么选?
从水凝胶柔性传感器写到毕业论文:AI 写作工具到底怎么选?

如果你在工学 / 纺织科学与工程 / 柔性功能电子器件与系统专业学习,大概率会遇到这样一项任务:围绕一类柔性应变传感器完成研究或毕业论文。比如做一个导电水凝胶柔性应变传感器,要设计材料配方、制备试样、测试拉伸过程中的电阻变化&#xf… · 2026/9/26 8:45:06

海康监控时间不准?NTP校时与时间同步配置全攻略
海康监控时间不准?NTP校时与时间同步配置全攻略

1. 监控时间不准这件事,比你想的要严重得多干弱电安防这行十几年,被问得最多的除了“摄像头怎么搜不到”,就是“录像回放时间对不上”。很多人觉得时间差个几分钟无所谓,直到出了事调录像才发现——画面里明明拍到人了&#xff0c… · 2026/9/26 8:45:06

Atlas 300V 24G推理卡部署YOLOv5全流程:从硬件到CANN实战
Atlas 300V 24G推理卡部署YOLOv5全流程:从硬件到CANN实战

最近在好几个AI部署群里,经常看到同一个问题:"Atlas 300V 24G是运算加速卡吗?""这卡能跑YOLO吗?"问的人多了,我觉得干脆把这阵子用Atlas 300V 24G跑通YOLOv5目标检测的完整过程整理出来。先给结论… · 2026/9/26 8:45:06

昇腾Atlas 300V 24G推理卡上部署YOLO全实战:从环境配置到性能调优
昇腾Atlas 300V 24G推理卡上部署YOLO全实战:从环境配置到性能调优

1. 硬件解读:Atlas 300V 24G 到底是张什么卡如果你还带着做深度学习训练的思路去选卡,看到"Atlas 300V 24G"大概率会先愣一下:24GB显存的卡,怎么价格比同显存的消费级显卡还便宜?是不是有什么坑?… · 2026/9/26 8:45:06

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码