循环队列(Circular Queue)
循环队列是队列的顺序存储结构的一种优化实现,旨在解决普通顺序队列中”假溢出”的问题。
假溢出问题
在普通顺序队列中,当元素从队首出队后,front 指针向后移动,被释放的队首空间无法再次使用。随着不断地入队和出队,rear 指针很快到达数组末尾,即使数组前端还有空闲位置,也无法再入队新元素,这种现象称为”假溢出”。
循环队列原理
循环队列将存储队列的数组在逻辑上视为一个环状结构。当 front 或 rear 指针超出数组最大下标时,通过取余运算(mod)将其绕回数组开头,从而复用之前出队释放的空间:
front = (front + 1) % MAXSIZE
rear = (rear + 1) % MAXSIZE
数据结构定义
#define MAXSIZE 100
typedef struct {
ElemType data[MAXSIZE];
int front; // 队首指针,指向队首元素
int rear; // 队尾指针,指向队尾元素的下一个位置
} SqQueue;队空与队满的判别
在循环队列中,队空和队满时 front == rear 都成立,因此需要额外的机制来区分:
-
牺牲一个存储单元:当 (rear + 1) % MAXSIZE == front 时认为队满。此时队列最多存储 MAXSIZE - 1 个元素。
- 队空条件:front == rear
- 队满条件:(rear + 1) % MAXSIZE == front
-
增设 size 变量:记录当前队列中的元素个数。size 0 时队空,size MAXSIZE 时队满。
-
增设 tag 标志位:每次入队成功将 tag 置为 1,出队成功置为 0。当 front == rear 时,通过 tag 判断是队空还是队满。
基本操作
- 入队:将元素放入 rear 指向的位置,rear = (rear + 1) % MAXSIZE
- 出队:取出 front 指向的元素,front = (front + 1) % MAXSIZE
- 队列长度:(rear - front + MAXSIZE) % MAXSIZE
循环队列通过取余运算,使得数组空间可以被循环利用,是队列顺序存储的主流实现方式。
链接到
- 上一个知识点:4.1 队列的基本概念
- 下一个知识点:4.3 链队列