因为front == rear既表示空也表示满,存在状态歧义;必须牺牲一个存储单元,使实际容量为N-1,空队列时front == rear,满队列时(rear + 1) % N == front。

用固定大小数组模拟队列时,为什么 front 和 rear 不能直接用下标相等判断空?
因为队列空和满在朴素实现里都会出现 front == rear,无法区分。必须预留一个“空位”或额外维护长度/标志位。
推荐做法是牺牲一个元素空间:数组容量为 N,实际最多存 N-1 个元素。此时:
- 空队列:
front == rear - 满队列:
(rear + 1) % N == front
这样仅靠两个指针就能无歧义判断状态,无需额外变量。
如何写一个线程不安全但简洁可用的循环数组队列?
适合教学、单线程嵌入式或竞赛场景。关键在于取模运算和边界检查的顺序。
立即学习“C++免费学习笔记(深入)”;
class ArrayQueue {
int* data;
int front, rear, capacity;
public:
ArrayQueue(int k) : capacity(k + 1), front(0), rear(0) {
data = new int[capacity];
}
bool enQueue(int value) {
if (isFull()) return false;
data[rear] = value;
rear = (rear + 1) % capacity;
return true;
}
bool deQueue() {
if (isEmpty()) return false;
front = (front + 1) % capacity;
return true;
}
int Front() { return isEmpty() ? -1 : data[front]; }
int Rear() { return isEmpty() ? -1 : data[(rear - 1 + capacity) % capacity]; }
bool isEmpty() { return front == rear; }
bool isFull() { return (rear + 1) % capacity == front; }
};
注意:Rear() 中 (rear - 1 + capacity) % capacity 是为避免负数取模未定义行为(尤其在 C++98/03 中)。
使用 std::vector 替代裸数组有哪些坑?
很多人想用 std::vector 自动管理内存,但直接 push_back/pop_front 效率极低——pop_front() 是 O(n)。
- 错误用法:
vec.pop_front()(不存在!需用vec.erase(vec.begin())) - 更糟的是:每次 pop 都移动后续所有元素
- 正确思路:仍用循环逻辑,只操作索引,
vector仅作底层存储容器
即:分配好 vector<int>(k+1)</int> 后,完全忽略其 size(),只按数组方式用 front/rear 索引访问 —— 这样才是 O(1) 操作。
为什么生产环境几乎不用手写数组队列?
不是不能写,而是没必要。C++ 标准库的 std::queue 默认基于 std::deque,它内部已做优化:分段连续内存 + 常数时间首尾操作,且自动扩容、异常安全、支持迭代器。
除非你明确需要:
- 确定的内存布局(如 DMA 缓冲区对齐)
- 零动态分配(bare-metal 或实时系统)
- 超低延迟且能接受固定上限
否则,直接用 std::queue<int> q</int> 更可靠。手写版本最容易出错的是取模边界、空满误判、析构时内存泄漏(忘了 delete[])。


















