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

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

个人主页-爱因斯晨

文章专栏-数据结构

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

文章目录

一、队列的基本概念

队列是一种先进先出(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

前端实战:手把手教你实现浏览器通知功能

前端实战:手把手教你实现浏览器通知功能

前端入门:浏览器通知功能从0到1实现指南 作为前端学习者,你可能见过这样的场景:打开网页版聊天工具,就算把浏览器最小化,桌面也会弹出“新消息”提醒;或者某些网站的活动通知,会直接显示在电脑/手机桌面上。这种功能就是「浏览器桌面通知」,今天我们就从零开始,搞懂它、学会用它。 一、先搞懂3个基础问题 1. 什么是浏览器桌面通知? 简单说,就是网页能在浏览器窗口外面(比如电脑桌面、手机屏幕)给你发提醒。哪怕浏览器最小化、甚至页面切到后台,只要权限允许,都能收到通知,不用一直盯着网页。 2. 什么时候会用到它? 常见场景很贴近日常: * 网页版微信/QQ的新消息提醒; * 工作系统的审批提醒、任务到期通知; * 电商网站的订单状态更新(比如“你的快递已发货”); * 新闻/小说网站的订阅内容更新提醒。 3. 用起来难吗?有什么限制? 不难!核心就2步:先让用户同意开启通知(申请权限)

By Ne0inhk
【最新版】防伪溯源一体化管理系统+uniapp前端+搭建教程

【最新版】防伪溯源一体化管理系统+uniapp前端+搭建教程

一.介绍 防伪溯源一体化管理系统基于ThinkPHP和Uniapp进行开发的多平台(微信小程序、H5网页)溯源、防伪、管理一体化独立系统,拥有强大的防伪码和溯源码双码生成功能(内置多种生成规则)、批量大量导出防伪和溯源码码数据、支持代理商管理端(团队管理、采购,邀请代理商、出库等功能)、支持招商经理管理端(可管理代理商团队,邀请代理商,数据统计,采购订单统计),支持出厂员端(出库、入库)、文章资讯、自定义展示查询页显示数据、查询记录、溯源记录追踪等功能。前后端无加密源代码和数据库,独立部署。 二.搭建环境 系统环境:CentOS、 运行环境:宝 塔 Linux 网站环境:Nginx 1.2.22 + MySQL 5.6 + PHP-7.4 常见插件:fileinfo

By Ne0inhk
全Web化智慧PACS/RIS系统源码 (纯B/S架构)

全Web化智慧PACS/RIS系统源码 (纯B/S架构)

告别传统C/S架构的笨重客户端!本套源码采用纯Web前端技术实现极速调阅,支持CT、核磁(MR)、DR、超声等多模态影像。内置专业级Web Viewer,支持MPR多平面重建、MIP、VR体渲染。自带RIS全流程管理。100%无加密源码交付,是医疗软件公司打造云PACS、区域影像中心的核心利器! 一、 为什么医疗企业都在寻找真正的WebPACS? 传统的PACS系统多采用C++或C#开发,需要医生在电脑上一台台安装庞大的客户端,维护成本极高,且无法适应如今“互联网医院”和“医共体远程诊断”的需求。 * 极速跨平台: 本系统基于HTML5+WebGL技术,医生只需打开浏览器,即可实现秒级加载百兆级影像,支持Windows、Mac甚至iPad移动阅片。 * 省去百万研发费: 医疗影像的底层解析(如窗宽窗位调节、各种DICOM Tag解析、图像无损压缩算法)是深水区,直接购买本源码,省去2-3年以上的底层图形学研发周期。 * 高价值变现: 本源码不仅可独立作为医院影像科管理系统出售,更可作为“影像插件”

By Ne0inhk

voidImageViewer:终极轻量级图像查看器,完美支持GIF/WEBP动画播放

voidImageViewer:终极轻量级图像查看器,完美支持GIF/WEBP动画播放 【免费下载链接】voidImageViewerImage Viewer for Windows with GIF support 项目地址: https://gitcode.com/gh_mirrors/vo/voidImageViewer voidImageViewer 是一款专为 Windows 平台设计的轻量级图像查看器,以其极速加载和流畅的动画播放工具功能而备受好评。这款工具不仅体积小巧,还能高效处理多种主流图像格式,为用户带来前所未有的图片浏览体验。 🚀 项目亮点:为什么选择voidImageViewer? 极速启动与运行:voidImageViewer 的启动速度令人惊叹,几乎在点击瞬间即可完成加载,大幅提升了工作效率。 资源占用极低:作为真正的轻量级应用,voidImageViewer 在后台运行时几乎不占用系统资源,确保您在进行其他工作时依然保持系统流畅。 跨格式兼容性:完美支持 BMP、GIF、ICO、JPG、TIF 和 WEBP 等多种图像格式,

By Ne0inhk