【数据结构】队列的应用:循环队列

考点频率 :★★★★★(数据结构必考,选择题每年至少1题,尤其爱考判空/判满条件)

难度 :⭐⭐⭐

建议:重点理解循环队列解决"假溢出"的原理,掌握判空、判满、元素个数三个公式

1️⃣ 为什么需要循环队列?

上一篇文章我们讲了顺序队列(数组实现)。它有一个严重的问题:假溢出(False Overflow)

假溢出的产生过程

  1. 初始状态:front = rear = 0,队列为空
  2. 入队 A、B、C、D:rear 移动到 4
  3. 出队 A、B:front 移动到 2
  4. 此时数组前两个位置(0和1)已经空闲,但 rear 已经在 4,无法再入队新元素

明明数组前面还有空闲空间,却无法使用------这就是"假溢出"。

解决方案 :把数组的首尾逻辑上连接起来 ,形成一个环形。当 rear 到达数组末尾时,下一步就绕回到数组开头------这就是循环队列(Circular Queue)

2️⃣ 循环队列的核心约定

循环队列使用两个指针:

  • front:指向队头元素的位置
  • rear:指向队尾元素的下一个位置(即下一个入队的位置)

三个核心公式(必背)

操作 公式
判空 front == rear
判满 (rear + 1) % MAXSIZE == front
元素个数 (rear - front + MAXSIZE) % MAXSIZE

⚠️ 注意 :循环队列中,为了区分"空"和"满",我们牺牲一个存储单元 ------当 (rear+1) % MAXSIZE == front 时判满,此时实际上还有一个空位没有放数据(即该位置不存储元素,仅作为"满"的判定标记,保证 front == rear 只代表空)。这是最常见的实现方式,考试也默认采用这种约定。

3️⃣ 为什么牺牲一个空间?

如果不牺牲空间,front == rear 可能代表"空"也可能代表"满":

情况 front rear 含义
空队列 0 0 front == rear
满队列 0 0 front == rear(绕了一圈回到原点)

同一个条件无法区分两种情况。所以牺牲一个空间 ,让"满"的条件变成 (rear+1) % MAXSIZE == front,这样就和"空"的条件区分开了。

4️⃣ 循环队列的基本操作

4.1 入队(Enqueue)

c 复制代码
int Enqueue(SeqQueue* q, int x) {
    if ((q->rear + 1) % MAXSIZE == q->front) {
        return -1;   // 队列已满
    }
    q->data[q->rear] = x;
    q->rear = (q->rear + 1) % MAXSIZE;
    return 0;
}

4.2 出队(Dequeue)

c 复制代码
int Dequeue(SeqQueue* q, int* x) {
    if (q->front == q->rear) {
        return -1;   // 队列为空
    }
    *x = q->data[q->front];
    q->front = (q->front + 1) % MAXSIZE;
    return 0;
}

4.3 元素个数计算

c 复制代码
int GetLength(SeqQueue* q) {
    return (q->rear - q->front + MAXSIZE) % MAXSIZE;
}

5️⃣ 例题详解

例题1 :某循环队列的数组大小为 6,front = 2rear = 5,则队列中的元素个数为( )。

A. 2

B. 3

C. 4

D. 5

解析

  • 元素个数 = (rear - front + MAXSIZE) % MAXSIZE
  • = (5 - 2 + 6) % 6 = 9 % 6 = 3
  • B

例题2 :某循环队列的数组大小为 8,若 front = 3,则 rear 为多少时表示队列已满?

A. 2

B. 3

C. 4

D. 6

解析

  • 判满条件:(rear + 1) % 8 == front
  • 代入 front = 3(rear + 1) % 8 == 3
  • 满足条件的 rear = 2(因为 (2+1)%8=3
  • A

例题3 (变式):某循环队列的数组大小为 5,当前 front = 3rear = 2,再入队一个元素后,frontrear 的值分别是多少?

解析

  • 当前元素个数 = (2 - 3 + 5) % 5 = 4 % 5 = 4
  • 数组大小为5,牺牲1个空间,最多存4个元素
  • 当前已经存了4个,队列已满,无法入队
  • 入队失败,frontrear 不变:front=3rear=2

答案 :无法入队,front=3rear=2

6️⃣ 三种处理"满/空"的方式

除了"牺牲一个空间"外,还有其他方式可以区分满和空。考试偶尔会涉及:

方案 判空 判满 说明
牺牲一个空间 front == rear (rear+1)%MAXSIZE == front 最常见,考试默认方案
增加 size 变量 size == 0 size == MAXSIZE 多一个变量记录元素个数,无需牺牲空间
增加 flag 变量 flag == 0 && front==rear flag == 1 && front==rear 用 flag 标记最后一次操作是入队还是出队

考试提示 :如果题目没有特别说明,默认采用牺牲一个空间 的方案。如果题目说"队列中有一个size变量记录元素个数",则判空判满条件要用 size

7️⃣ 记忆口诀

循环队列首尾连,假溢出问题不再现。

front == rear 为空,(rear+1)%max == front 为满。

元素个数公式记:(rear - front + max) % max

8️⃣ 小测验(评论区对答案)

某循环队列的数组大小为 10,当前 front = 6rear = 4,队列中元素个数为( )。再入队两个元素后,frontrear 的值分别是多少?

A. 8;front=6rear=6

B. 8;front=6rear=8

C. 6;front=6rear=8

D. 6;front=6rear=6

🔔 本专栏日更,点击头像 → 专栏《软考中级高频考点》订阅,第一时间接收新内容

#软考中级 #软件设计师 #循环队列 #队列 #数据结构 #软考备考

相关推荐
Winner_hwx1 小时前
python拓展
算法
跳跃的芋头人1 小时前
RefactoringUI 阅读笔记1 - 从草稿开始
笔记
TAN-90°-1 小时前
Deep Learning for Computer Vision——Image Classification with Linear Classifiers
python·深度学习·算法·计算机视觉·线性回归
是上好佳佳佳呀2 小时前
【深度学习|DAY03】神经网络深度学习笔记(上):框架总览、参数初始化与激活函数
笔记·深度学习·神经网络
阿pin2 小时前
Java随笔-红黑树
java·python·算法·红黑树
Hi李耶2 小时前
【LeetCode】17.电话号码的字母组合
算法·leetcode·职场和发展
zhangrelay2 小时前
ROS 2 Lyrical 第2章 ROS 2系统架构与核心概念
linux·笔记·学习·ubuntu·ros2
江畔柳前堤10 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Doraemomo11 小时前
数据结构-环形链表
java·数据结构·链表