目录
一、队列的基本概念与核心特性
1.定义
**队列:**一种只允许在队尾插入元素,在队头删除元素的线性表。
这一特性决定了队列的**"先进先出(FIFO)"**原则,即最早进入队列的元素,最早被取出。
2.核心术语
- **队头:**允许删除的一端,指向队列中第一个元素的位置。
- **队尾:**允许插入的一段,指向队列中最后一个元素的下一个位置。
- 空队列:当队头和队尾指向同一位置。
- **满队列:**队尾达到存储结构的最大容量。
3.常用操作
- **初始化:**创建一个空队列。
- **判空:**判断队列是否为空。
- **判满:**判断队列是否已满,仅顺序队列需要。
- **入队:**在队尾插入一个新元素。
- **出队:**在队头删除一个元素。
- **获取队头元素:**返回队头元素的值,但不删除该元素。
二、队列的常见分类
1.普通队列
- **顺序队列:**基于数组实现,需维护队首和队尾指针/下标;缺点是易出现假溢出。
- 链式队列:基于链表实现,用头节点指向队首、尾节点指向队尾,支持动态扩容,无假溢出问题。
**假溢出:**数组尾部已满但头部有空余空间
2.循环队列
为解决顺序队列的假溢出问题,将数组逻辑上构造成环形,让 head 和 tail 指针在数组中循环移动。其核心是通过取模运算实现 "环形"。
基于效率的考虑,在入队和出队的时候,head 和 tail 均采用直接自增(++)操作。但如果一直自增的话,head 和 tail 会越界。为了准确表达队空、队满的情况,做以下约束:
- **判空条件:**head == tail
- 判满条件:(tail + 1) % tlen == head(预留一个空位置避免与判空条件混淆)
3.双端队列
允许在队首和队尾同时执行入队 / 出队操作的特殊队列,可灵活实现 "栈"(仅用一端操作)或 "普通队列" 的功能,常用于滑动窗口等算法场景。
4.优先级队列
打破 FIFO 原则的特殊队列,元素按优先级排序,优先级最高的元素优先出队,底层通常基于堆实现,常用于任务调度(如嵌入式系统的中断优先级管理)。
三、队列的C语言实现
1.循环顺序队列
固定容量,适合内存受限的嵌入式场景
cpp
typedef int DATATYPE;
typedef struct queue {
DATATYPE *ptr;
int tlen;
int head;
int tail;
}SeqQueue;
// 创建队列
SeqQueue *CreateSeqQueue(int len);
// 出队操作
DATATYPE QuitSeqQueue(SeqQueue *queue);
// 入队操作
int EnterSeqQueue(SeqQueue *queue, DATATYPE data);
// 判空操作
int IsEmptySeqQueue(SeqQueue *queue);
//判满操作
int IsFullSeqQueue(SeqQueue *queue);
// 销毁队列
int DestroySeqQueue(SeqQueue *queue);
为方便理解,下面展示循环顺序队列的结构图:

2.链式队列
动态扩容,适合数据量不固定的场景
cpp
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;
// 创建链队
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);
为方便理解,下面展示链式队列的结构图:

四、队列的核心操作复杂度
|--------|------------|----------|
| 操作 | 循环顺序队列 | 链式队列 |
| 入队 | O(1) | O(1) |
| 出队 | O(1) | O(1) |
| 判空/判满 | O(1) | O(1) |
| 获取队首 | O(1) | O(1) |
| 空间复杂度 | O(n)(固定) | O(n)(动态) |
五、队列的典型应用
- 中断数据缓冲:嵌入式系统中,串口 / ADC 等外设的中断接收数据可存入队列,主程序从队列中读取处理,避免数据丢失(如 STM32 的 USART 接收缓冲)。
- 任务调度:RTOS(如 FreeRTOS)中,就绪任务队列按优先级或 FIFO 顺序调度,优先级队列可实现高优先级任务优先执行。
- 广度优先搜索(BFS):算法中用于层级遍历(如二叉树层序遍历、迷宫最短路径求解)。
- 消息队列:多线程 / 多进程间的通信机制,实现数据的异步传递。