队列

队列
THEDI队列
队列介绍
队列(Queue):一种线性表数据结构,遵循
先进先出FIFO(First In First Out)原则,只允许在一端插入元素(队尾),在另一端删除元素(队头)。
- 典型场景:排队、缓冲区、消息队列、广度优先搜索(BFS)、生产者-消费者等。
- 逻辑概念:
- front(队头):指向队列中要被取出的元素。
- rear(队尾):指向下一个可插入的位置或当前队尾(实现上有细微差别)。
- enqueue(入队/入列)与 dequeue(出队/出列)。
基本操作
- 入队(enqueue):在队尾插入元素
- 出队(dequeue):从队头删除元素
队列的实现方式
与线性表类似,队列常见的存储方式有两种:顺序存储 和 链式存储。
- 顺序存储队列:使用一段连续的存储空间(如数组),依次存放队列中从队头到队尾的元素。通过指针
front标记队头元素的位置,rear标记队尾元素的位置。 - 链式存储队列:采用单链表实现,元素按插入顺序依次链接。
front指向链表的头节点(即队头元素),rear指向链表的尾节点(即队尾元素)。
需要注意的是,front 和 rear 的具体指向方式可能因实现细节而异。为简化算法或代码,有时front会指向队头元素的前一个位置,rear也可能指向队尾元素的下一个位置。具体以实际实现为准。
顺序队列
这种方法实现较为简单,入队和出队只需要控制front和rear指针的移动即可。
但是这种方法在队列满的时候(queue->rear == queue->size)的时候,就无法再插入新元素,即使前面有空位也无法利用,导致假溢出的问题
假溢出:指队列存储区未满时发生溢出的现象。该现象常见于顺序存储队列结构中:顺序队列的前端有空间但因未复用导致队尾指针到达数组末尾时无法再入队,造成“假满”现象。
- 如图为初始队列:
- 入队出队后造成的假溢出:前面有空间但是无法入队
为解决这个问题,常用两种方法:
- 方法一:每次出队后整体前移元素
这样可以利用前面的空位,但每次出队都要移动所有元素,效率低,时间复杂度O(n),不推荐。
- 方法二:使用循环队列
将队列的首尾视为相连,通过取模运算实现指针的循环移动,从而充分利用存储空间。采用循环队列后,所有基本操作的时间复杂度均为O(1),高效且无假溢出问题。
循环队列(顺序存储循环队列)
**循环队列: **是一种特殊的队列结构,使用
数组完成,它将顺序队列的数组看作一个首尾相接的环形空间,从而解决了顺序队列中可能出现的假溢出问题。在循环队列中,队列的头尾指针可以通过模运算实现循环移动。
循环队列结构体定义
1 | /** 循环队列容量,默认值 8;可在编译期通过 -DCQ_CAPACITY=NN 覆盖 */ |
ElemType* data_base:数据项,这里使用一个指针存储数组的首地址,后续我们仍然可以像操作数组一样使用下标访问,我们也可以直接将其设置为固定长度的数组如:ElemType data[CQ_CAPACITY]
front: 队首指针:指向队列的第一个元素
rear:队尾指针:指向队列最后一个元素的下一位置,也叫做下一个入队元素位置
size: 当前元素个数
API设计
1 | // 初始化/销毁 |
循环队列源码实现
github仓库:https://github.com/keqiudi/Queue/tree/master/circular_queue
circular_queue.h
1 |
|
circular_queue.c
1 | // |
测试代码
1 |
|
输出结果:
1 | C:\Users\keqiu\myProjects\CLionProjects\C\Queue\circular_queue\build\circular_queue.exe |
链式队列(链式存储队列)
链式队列:是一种用链表实现的队列结构,每个元素封装为一个节点(包含数据域和指针域),队列通过两个指针维护首尾:front指向队头(下一个将被出队的节点),rear指向队尾(新节点在此后追加)。链式队列不依赖连续内存,也没有固定容量,因此不会出现顺序队列的假溢出问题,适合元素数量不可预知或需要动态扩展的场景。
链式队列结构体定义
1 | /** 队列中元素的数据类型(可根据需要调整) */ |
API设计
1 | // 初始化/销毁 |
链式队列因为基于链表实现,所以没有判空和容量相关的api
链式队列源码实现
github仓库:https://github.com/keqiudi/Queue/tree/master/linked_queue
linked_queue.h
1 | // |
linked_queue.c
1 |
|
测试代码
1 |
|
输出结果:
1 | C:\Users\keqiu\myProjects\CLionProjects\C\Queue\linked_queue\build\linked_queue.exe |











