数据结构--队列

队列(Queue)

一、基本概念

1.1 定义

队列是只允许在一端进行插入(队尾),在另一端进行删除(队头)的线性表。

  • 队尾(Rear):允许插入的一端

  • 队头(Front):允许删除的一端

特点:先进先出(FIFO - First In First Out)

1.2 主要用途

  • 数据缓冲:解决生产者和消费者之间的速度不匹配问题

  • 任务调度:操作系统中的进程调度

  • 广度优先搜索:图算法中的实现基础

二、顺序队列(循环队列)

2.1 基本结构

typedef int DATATYPE;

typedef struct queue {

DATATYPE *ptr; // 指向队列数组的指针

int tlen; // 队列总容量

int head; // 队头指针

int tail; // 队尾指针

} SeqQueue;

2.2 关键问题与解决方案

  • 问题:顺序队列中head和tail一直递增会导致越界

  • 解决方案:循环队列(模运算)

head = (head + 1) % size;

tail = (tail + 1) % size;

2.3 队空与队满的判断

  • 队空条件:head == tail

  • 队满条件:(tail + 1) % size == head

说明:牺牲一个存储单元来区分队空和队满

2.4 基本操作接口

// 创建队列

SeqQueue *CreateSeqQueue(int len);

// 销毁队列

int DestroySeqQueue(SeqQueue *queue);

// 入队

int EnterSeqQueue(SeqQueue *queue, DATATYPE data);

// 出队

DATATYPE QuitSeqQueue(SeqQueue *queue);

// 判断队空

int IsEmptySeqQueue(SeqQueue *queue);

// 判断队满

int IsFullSeqQueue(SeqQueue *queue);

三、链式队列

3.1 数据结构定义

数据节点结构

typedef struct person {

char name[32];

char sex;

int age;

int score;

} DATATYPE;

typedef struct quenode {

DATATYPE data;

struct quenode *next;

} LinkQueNode;

队列管理结构

typedef struct {

LinkQueNode *head; // 队头指针

LinkQueNode *tail; // 队尾指针

int clen; // 队列当前长度

} LinkQue;

3.2 链式队列特点

  • 无需预先分配固定空间

  • 不会出现假溢出

  • 动态扩展,更加灵活

  • 需要额外的指针存储空间

3.3 基本操作接口

// 创建队列

LinkQue *CreateLinkQue();

// 入队

int EnterLinkQue(LinkQue *lq, DATATYPE *newnode);

// 出队

int QuitLinkQue(LinkQue *lq);

// 获取队头元素

DATATYPE *GetHeadLinkQue(LinkQue *lq);

// 获取队列大小

int GetSizeLinkQue(LinkQue *lq);

// 判断队空

int IsEmptyLinkQue(LinkQue *lq);

// 销毁队列

int DestroyLinkQue(LinkQue *lq);

四、两种队列对比

|-------|----------|--------|
| 特性 | 顺序队列(循环) | 链式队列 |
| 存储方式 | 连续内存数组 | 离散内存节点 |
| 空间限制 | 固定大小 | 动态扩展 |
| 溢出问题 | 可能假溢出 | 无假溢出 |
| 实现复杂度 | 简单 | 较复杂 |
| 适用场景 | 数据量固定/已知 | 数据量变化大 |
| 内存使用 | 效率高 | 有指针开销 |

五、应用场景总结

缓冲区管理

  • 网络数据包缓冲

  • 打印机任务队列

  • 消息队列系统

算法实现

  • 广度优先搜索(BFS)

  • 缓存淘汰算法(FIFO策略)

系统调度

  • CPU进程调度

  • 磁盘I/O请求调度

数据流处理

  • 实时数据流缓冲

  • 生产者-消费者模式

六、重要注意事项

  • 循环队列的空满判断必须使用(tail+1)%size == head判断队满

  • 链式队列销毁需要遍历释放所有节点内存

  • 线程安全:在多线程环境下使用队列需要考虑同步机制

  • 边界处理:所有操作都要检查队列为空/满的情况

七、性能考虑

  • 时间复杂度:两种队列的入队、出队操作都是O(1)

  • 空间效率:顺序队列更优,链式队列有指针开销

  • 缓存友好性:顺序队列的连续内存访问更适合CPU缓存

相关推荐
m0_626535203 小时前
learning english 笔记
笔记
mit6.8243 小时前
八皇后变题hash|网格dp
算法
bybitq3 小时前
LeetCode-437-路径总和3
算法
im_AMBER3 小时前
数据结构 18 【复习】广义表 | 各种内部排序 | 二叉排序树的平均查找长度 ASL
数据结构·笔记·学习·排序算法
世人万千丶3 小时前
鸿蒙跨端框架Flutter学习day 2、常用UI组件-层叠布局 Stack & Positioned
学习·flutter·ui·实时互动·harmonyos·鸿蒙
好奇龙猫3 小时前
【人工智能学习-AI入试相关题目练习-第四次】
人工智能·学习
马克学长3 小时前
SSM学生出国境学习交流管理87153(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·学习·ssm 框架·学生出国境管理·在线申请
chilavert3183 小时前
DashGO框架开发应用的笔记-1
笔记
鱼跃鹰飞3 小时前
Leetcode尊享面试100题:1060. 有序数组中的缺失元素
算法·leetcode·面试
啊我不会诶3 小时前
AtCoder Beginner Contest 438 vp补题
算法