标记位法用布尔变量tag区分循环队列空满状态:front==rear且tag为false时为空,为true时为满;不牺牲空间、避免计数竞争,但需严格维护tag更新。

循环队列中,front == rear 既可能表示空,也可能表示满,这是所有判定方案要解决的核心矛盾。标记位法不牺牲空间、也不额外计数,靠一个布尔变量辅助区分语义,适合对内存敏感又需逻辑严谨的场景。
标记位法的基本原理
引入一个布尔变量(如 tag),初始值为 false,用于记录最后一次操作类型:
- 每次成功入队后,将 tag 置为 true
- 每次成功出队后,将 tag 置为 false
- 当 front == rear 时,结合 tag 值即可唯一判断状态
空与满的具体判定条件
在 front == rear 成立的前提下:
- 队列为空:tag == false(说明刚执行了出队,且队列已清空)
- 队列为满:tag == true(说明刚执行了入队,且恰好填满导致 rear 追上 front)
注意:该方法要求 front 和 rear 的初始值必须相同(通常为 0 或 -1),且所有入队/出队操作都严格更新 tag,否则状态会错乱。
实际编码中的关键细节
标记位法看似简单,但容易在边界处出错。需特别注意以下几点:
- 入队前先判满(用 front == rear && tag),满则拒绝;成功入队后才更新 rear 和 tag
- 出队前先判空(用 front == rear && !tag),空则拒绝;成功出队后才更新 front 和 tag
- 初始化时若设 front = rear = -1,需确保首次入队后 tag 正确置为 true,且后续计算下标时做模运算适配
- 避免在异常路径(如内存分配失败、指针越界)中遗漏 tag 更新,否则会导致状态永久失准
与其他方案的对比要点
标记位法在资源受限系统中有其不可替代性:
- 相比“牺牲单元法”,它100% 利用数组空间,不浪费任何存储单元
- 相比“计数器法”,它不依赖 size 变量的累加/递减正确性,规避了多线程下计数竞争风险(若未加锁)
- 缺点是逻辑分支略多,每次入队/出队都要维护 tag,代码可读性稍弱于计数器法










