数据结构 | 队列:从概念到实战

数据结构 | 队列:从概念到实战

个人主页-爱因斯晨

文章专栏-数据结构

继续加油!
在这里插入图片描述

文章目录

一、队列的基本概念

队列是一种先进先出(FIFO,First In First Out) 的线性数据结构,仅允许在一端进行插入操作(队尾),另一端进行删除操作(队头)。

生活中的队列场景:

  • 银行窗口排队办理业务
  • 打印机任务队列
  • 消息队列中的消息传递

二、队列的核心操作

  1. 初始化(InitQueue:创建一个空队列
  2. 入队(EnQueue:在队尾插入元素
  3. 出队(DeQueue:从队头删除元素
  4. 获取队头元素(GetFront:返回队头元素值
  5. 判空(IsEmpty:判断队列是否为空
  6. 销毁(DestroyQueue:释放队列占用的内存

三、C 语言实现队列

3.1 顺序队列(数组实现)

顺序队列使用数组存储元素,通过队头指针(front)和队尾指针(rear)标记队列边界。

#include<stdio.h>#include<stdlib.h>#defineMAX_SIZE100// 队列最大容量// 顺序队列结构体typedefstruct{int data[MAX_SIZE];int front;// 队头指针(指向队头元素)int rear;// 队尾指针(指向队尾元素的下一个位置)} SeqQueue;// 初始化队列voidInitQueue(SeqQueue *q){ q->front =0; q->rear =0;}// 判空intIsEmpty(SeqQueue *q){return q->front == q->rear;}// 判满intIsFull(SeqQueue *q){return(q->rear +1)% MAX_SIZE == q->front;// 预留一个空间区分空满}// 入队intEnQueue(SeqQueue *q,int value){if(IsFull(q)){printf("队列已满,无法入队\n");return0;// 入队失败} q->data[q->rear]= value; q->rear =(q->rear +1)% MAX_SIZE;// 循环移动队尾指针return1;// 入队成功}// 出队intDeQueue(SeqQueue *q,int*value){if(IsEmpty(q)){printf("队列为空,无法出队\n");return0;// 出队失败}*value = q->data[q->front]; q->front =(q->front +1)% MAX_SIZE;// 循环移动队头指针return1;// 出队成功}// 获取队头元素intGetFront(SeqQueue *q,int*value){if(IsEmpty(q)){printf("队列为空,无队头元素\n");return0;}*value = q->data[q->front];return1;}// 测试顺序队列intmain(){ SeqQueue q;InitQueue(&q);// 入队操作EnQueue(&q,10);EnQueue(&q,20);EnQueue(&q,30);// 获取队头元素int frontVal;GetFront(&q,&frontVal);printf("队头元素:%d\n", frontVal);// 输出:10// 出队操作int deVal;DeQueue(&q,&deVal);printf("出队元素:%d\n", deVal);// 输出:10// 再次获取队头GetFront(&q,&frontVal);printf("新队头元素:%d\n", frontVal);// 输出:20return0;}

顺序队列特点

  • 优点:实现简单,访问速度快
  • 缺点:容量固定,存在 “假溢出” 问题(需用循环队列优化)

3.2 链式队列(链表实现)

链式队列使用链表存储元素,队头指针指向头节点,队尾指针指向尾节点。

#include<stdio.h>#include<stdlib.h>// 节点结构体typedefstructNode{int data;structNode*next;} Node;// 链式队列结构体typedefstruct{ Node *front;// 队头指针(指向头节点) Node *rear;// 队尾指针(指向尾节点)} LinkQueue;// 初始化队列voidInitQueue(LinkQueue *q){// 创建头节点(不存储数据) Node *head =(Node*)malloc(sizeof(Node)); head->next =NULL; q->front = head; q->rear = head;}// 判空intIsEmpty(LinkQueue *q){return q->front == q->rear;}// 入队voidEnQueue(LinkQueue *q,int value){// 创建新节点 Node *newNode =(Node*)malloc(sizeof(Node)); newNode->data = value; newNode->next =NULL;// 插入到队尾 q->rear->next = newNode; q->rear = newNode;// 更新队尾指针}// 出队intDeQueue(LinkQueue *q,int*value){if(IsEmpty(q)){printf("队列为空,无法出队\n");return0;} Node *temp = q->front->next;// 待删除节点*value = temp->data; q->front->next = temp->next;// 如果删除的是最后一个节点,需更新队尾指针if(q->rear == temp){ q->rear = q->front;}free(temp);// 释放节点内存return1;}// 获取队头元素intGetFront(LinkQueue *q,int*value){if(IsEmpty(q)){printf("队列为空,无队头元素\n");return0;}*value = q->front->next->data;return1;}// 销毁队列voidDestroyQueue(LinkQueue *q){// 释放所有节点while(q->front !=NULL){ q->rear = q->front->next;free(q->front); q->front = q->rear;}}// 测试链式队列intmain(){ LinkQueue q;InitQueue(&q);// 入队EnQueue(&q,100);EnQueue(&q,200);EnQueue(&q,300);// 获取队头int frontVal;GetFront(&q,&frontVal);printf("队头元素:%d\n", frontVal);// 输出:100// 出队int deVal;DeQueue(&q,&deVal);printf("出队元素:%d\n", deVal);// 输出:100// 销毁队列DestroyQueue(&q);return0;}

链式队列特点

  • 优点:容量动态扩展,不存在溢出问题
  • 缺点:需要额外空间存储指针,操作稍复杂

四、队列的应用场景

  1. 广度优先搜索(BFS):在二叉树层次遍历、图的遍历中常用
  2. 缓冲处理:如键盘输入缓冲、网络数据接收缓冲
  3. 任务调度:操作系统中的进程调度、线程池任务调度
  4. 消息传递:分布式系统中的消息队列(如 RabbitMQ)

五、两种实现的对比选择

场景推荐实现理由
已知数据量且固定顺序队列效率更高,无需额外指针开销
数据量动态变化链式队列避免空间浪费和溢出问题
频繁插入删除链式队列操作更高效(O (1) 时间复杂度)
对内存使用敏感顺序队列内存连续分配,缓存利用率高

Read more

基于YOLO26/11/v8算法的Web目标检测系统,人脸表情识别系统,Django+Vue3 的前后端分离,实现摄像头实时识别,YOLO26/YOLO11/v8 + LLM大模型智能分析,科研必备

基于YOLO26/11/v8算法的Web目标检测系统,人脸表情识别系统,Django+Vue3 的前后端分离,实现摄像头实时识别,YOLO26/YOLO11/v8 + LLM大模型智能分析,科研必备

✨ 更新日志 * ✔️ 2026/3/3,2.0 版本,前端导航栏改为侧边栏系统,视频流采用websocket框架延迟更低, YOLO26/YOLO11/YOLOv8 视频流更稳定,在之前的系统增加 LLM 大模型智能分析,是科研必备,支持 YOLO26/11/v8 分类模型、目标检测、分割、obb、关键点检测任务,还支持双模型联合检测与识别,如人脸表情识别、人脸识别等一些识别任务需要检测模型与分类模型共同完成,在人脸表情识别中,单独使用检测模型去识别人脸表情也不是不可以,但有一个问题数据集如果全是头部照片的话,当模型预测的照片是全身照片时,模型识别准确率就没有这么高了, 那么这时候可以用检测模型识别人脸,把人脸信息输入到表情分类模型进行分类即可,反正这是一个通用的系统,更换自己模型即可,大家懂得都懂的,更多功能看下文即可。 摘要 在人工智能迈向通用化(AGI)的今天,“视觉感知 + 语言理解”的多模态联合是未来的趋势。单纯的检测画框已经无法满足复杂的业务需求,如何让系统“看懂”

By Ne0inhk
NTC热敏电阻温度换算太复杂?一篇搞定所有算法!

NTC热敏电阻温度换算太复杂?一篇搞定所有算法!

一、NTC热敏电阻是什么         在嵌入式系统开发中,温度测量是一个常见需求。NTC(负温度系数)热敏电阻因其成本低、灵敏度高而被广泛应用。本文将详细介绍如何利用一个简单的分压电路,结合STM32的ADC和数学公式,实现高精度的温度测量。         NTC是Negative Temperature Coefficient的缩写,意为“负温度系数”。其核心特性是电阻值随温度升高而呈指数型下降。这种特性使其对温度变化极为敏感,非常适合作为温度传感器。 * 工作原理:其半导体材料内部的载流子数量随温度升高而增加,导致电阻下降。 * 关键参数: * R25:在25°C(即298.15K)时的零功率电阻值。这是最重要的标称值,例如常见的10kΩ、100kΩ等。在下文计算中,我们的R0就是指这个值。 * B值:材料常数,单位为开尔文(K)。它描述了NTC电阻-温度曲线的形状,代表了在T1和T2两个温度之间的“斜率”。B值越大,在相同温度变化下,电阻变化率越高。常用值如3380K, 3950K等。 * 优点:成本低、灵敏度高、体积小。

By Ne0inhk
TOON:一种为大模型设计的JSON压缩型数据结构

TOON:一种为大模型设计的JSON压缩型数据结构

目录 TOON:一种为大模型设计的JSON压缩型数据结构 一、精准定义,什么是 TOON? 1、JSON 数据格式的局限性 2、TOON 的结构与优势 3、TOON 数据结构的主要特征 4、媒体类型与文件拓展名 二、举例:JSON 与 TOON 描述同一组数据分别是什么样 三、结语         作者:watermelo37         ZEEKLOG优质创作者、华为云云享专家、阿里云专家博主、腾讯云“创作之星”特邀作者、火山KOL、支付宝合作作者,全平台博客昵称watermelo37。         一个假装是giser的coder,做不只专注于业务逻辑的前端工程师,Java、Docker、Python、LLM均有涉猎。 --------------------------------------------------------------------- 温柔地对待温柔的人,包容的三观就是最大的温柔。 ---------------------------------------------------------------------

By Ne0inhk
《算法题讲解指南:优选算法-分治-归并》--47.归并排序,48.数组中的逆序对

《算法题讲解指南:优选算法-分治-归并》--47.归并排序,48.数组中的逆序对

🔥小叶-duck:个人主页 ❄️个人专栏:《Data-Structure-Learning》 《C++入门到进阶&自我学习过程记录》《算法题讲解指南》--优选算法 ✨未择之路,不须回头 已择之路,纵是荆棘遍野,亦作花海遨游 目录 47.归并排序 题目链接: 题目描述: 题目示例: 解法(归并排序): 算法思路: C++算法代码: 算法总结及流程解析: 48.数组中的逆序对 题目链接: 题目描述: 题目示例: 解法(利用归并排序的过程——分治): 算法思路: C++算法代码: 算法总结及流程解析: 结束语 47.归并排序 题目链接: 215. 数组912. 排序数组 - 力扣(LeetCode)215.

By Ne0inhk