循环队列将顺序队列的逻辑上首尾相连,形成"环",以解决假溢出问题。
普通顺序队列:入队时 rear 向后移动,出队时 front 向后移动;当 rear 到达数组末尾时,即使前面有空位也无法入队——这就是假溢出。
假溢出示例(MaxSize=6):
┌───┬───┬───┬───┬───┬───┐
│ │ │ c │ d │ │ │
└───┴───┴───┴───┴───┴───┘
0 1 2 3 4 5
↑f ↑r
front=2, rear=4(rear 已到末尾,但 0,1,5 仍空着)
#define MaxSize 6
typedef struct {
ElemType data[MaxSize];
int front, rear; // 队头和队尾指针
} SqQueue;
约定:队尾指针的下一个位置是队头时,认为队满。rear 指向下一个空位置。
队满示例(MaxSize=6,牺牲一个位置):
┌───┬───┬───┬───┬───┬───┐
│ e │ f │ a │ b │ c │ d │
└───┴───┴───┴───┴───┴───┘
0 1 2 3 4 5
↑r ↑f
front=2, rear=1,(rear+1)%6 = 2 = front → 队满
实际存了 5 个,最多能存 MaxSize-1 = 5 个
typedef struct {
ElemType data[MaxSize];
int front, rear;
int size; // 当前元素个数
} SqQueue2;
typedef struct {
ElemType data[MaxSize];
int front, rear;
int tag; // 最近一次操作:0=删除,1=插入
} SqQueue3;
| 方案 | 空间利用 | 额外开销 | 复杂度 |
|---|---|---|---|
| 牺牲一个单元 | MaxSize-1 | 无 | 简单 |
| 增加 size | MaxSize | 一个 int | 简单 |
| 增加 tag | MaxSize | 一个 int | 略复杂 |
$MaxSize=6$,当前 $front=2$,$rear=4$,牺牲一个单元方案:
$MaxSize=8$,$front=5$,$rear=2$ → 长度 $(2 - 5 + 8) \% 8 = 5$。验证:位置 5,6,7,0,1 共 5 个元素 ✓
$MaxSize=6$,初始 $front=rear=0$,执行:入队 1,2,3 → 出队 → 入队 4,5 → 出队 → 入队 6
| 操作 | front | rear | 长度 | 队列内容 |
|---|---|---|---|---|
| 初始 | 0 | 0 | 0 | 空 |
| 入1 | 0 | 1 | 1 | [1] |
| 入2 | 0 | 2 | 2 | [1,2] |
| 入3 | 0 | 3 | 3 | [1,2,3] |
| 出队 | 1 | 3 | 2 | [2,3] |
| 入4 | 1 | 4 | 3 | [2,3,4] |
| 入5 | 1 | 5 | 4 | [2,3,4,5] |
| 出队 | 2 | 5 | 3 | [3,4,5] |
| 入6 | 2 | 0 | 4 | [3,4,5,6] |
判满:$(0+1)\%6=1 \neq 2$,未满。
| 条件 | 牺牲一个单元 | 增加 size | 增加 tag |
|---|---|---|---|
| 队空 | $front==rear$ | $size==0$ | $front==rear$ 且 $tag==0$ |
| 队满 | $(rear+1)\%M==front$ | $size==MaxSize$ | $front==rear$ 且 $tag==1$ |
| 长度 | $(rear-front+M)\%M$ | $size$ | $(rear-front+M)\%M$ |
(暂无关联知识点)
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。