数据结构--队列

队列(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缓存

相关推荐
奶茶精Gaaa几秒前
工具分享--json在线转换工具
学习
爱敲代码的TOM6 分钟前
数据结构总结
数据结构
CoderCodingNo16 分钟前
【GESP】C++五级练习题 luogu-P1865 A % B Problem
开发语言·c++·算法
wdfk_prog17 分钟前
[Linux]学习笔记系列 -- [drivers][I2C]I2C
linux·笔记·学习
大闲在人26 分钟前
7. 供应链与制造过程术语:“周期时间”
算法·供应链管理·智能制造·工业工程
盐焗西兰花28 分钟前
鸿蒙学习实战之路-Reader Kit自定义字体最佳实践
学习·华为·harmonyos
小熳芋29 分钟前
443. 压缩字符串-python-双指针
算法
Charlie_lll39 分钟前
力扣解题-移动零
后端·算法·leetcode
chaser&upper40 分钟前
矩阵革命:在 AtomGit 解码 CANN ops-nn 如何构建 AIGC 的“线性基石”
程序人生·算法
weixin_499771551 小时前
C++中的组合模式
开发语言·c++·算法