在循环队列 中,判断队列的 空 、满 以及 长度 是关键操作。以下是循环队列的相关判断条件的详细罗列:
1. 判断队列是否为空
条件 :队头指针 front 等于队尾指针 rear。
代码实现:
Cbool IsEmpty(SqQueue Q) {
return Q.front == Q.rear;
}
解释:
- 当
front == rear时,队列中没有元素,队列为空。
2. 判断队列是否为满
条件 :队尾指针 rear 的下一个位置是队头指针 front,即 (rear + 1) % MAXQSIZE == front。
代码实现:
Cbool IsFull(SqQueue Q) {
return (Q.rear + 1) % MAXQSIZE == Q.front;
}
解释:
- 循环队列中,为了区分队列空和队列满的情况,通常会牺牲一个元素空间。
- 当
(rear + 1) % MAXQSIZE == front时,队列已满。
3. 计算队列的长度
条件 :队列的长度为 (rear - front + MAXQSIZE) % MAXQSIZE。
代码实现:
Cint QueueLength(SqQueue Q) {
return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}
解释:
rear - front可能为负数(当rear绕到front前面时),因此加上MAXQSIZE确保结果为正。- 通过取模运算
% MAXQSIZE,确保结果在0到MAXQSIZE - 1之间。
4. 入队操作的条件
条件 :队列未满,即 (rear + 1) % MAXQSIZE != front。
代码实现:
CStatus EnQueue(SqQueue &Q, QElemType e) {
if ((Q.rear + 1) % MAXQSIZE == Q.front) {
return ERROR; // 队列已满,无法入队
}
Q.base[Q.rear] = e; // 将元素插入队尾
Q.rear = (Q.rear + 1) % MAXQSIZE; // 队尾指针后移
return OK;
}
解释:
- 如果队列未满,则将元素插入队尾,并将
rear指针后移。 - 通过取模运算
% MAXQSIZE,确保rear指针在数组范围内循环。
5. 出队操作的条件
条件 :队列不为空,即 front != rear。
代码实现:
CStatus DeQueue(SqQueue &Q, QElemType &e) {
if (Q.front == Q.rear) {
return ERROR; // 队列为空,无法出队
}
e = Q.base[Q.front]; // 取出队头元素
Q.front = (Q.front + 1) % MAXQSIZE; // 队头指针后移
return OK;
}
解释:
- 如果队列不为空,则取出队头元素,并将
front指针后移。 - 通过取模运算
% MAXQSIZE,确保front指针在数组范围内循环。
6. 队列的初始化
条件 :队头指针 front 和队尾指针 rear 都初始化为 0。
代码实现:
CStatus InitQueue(SqQueue &Q) {
Q.base = new QElemType[MAXQSIZE]; // 动态分配数组空间
if (!Q.base) {
exit(OVERFLOW); // 内存分配失败
}
Q.front = Q.rear = 0; // 初始化队头和队尾指针
return OK;
}
解释:
- 初始化时,队列为空,因此
front和rear都指向数组的起始位置。
7. 队列的销毁
条件 :释放队列的存储空间,并将 front 和 rear 置为 0。
代码实现:
CStatus DestroyQueue(SqQueue &Q) {
if (Q.base) {
delete[] Q.base; // 释放数组空间
}
Q.front = Q.rear = 0; // 重置队头和队尾指针
return OK;
}
解释:
- 销毁队列时,释放动态分配的数组空间,并将指针重置。
总结
循环队列的关键判断条件如下:
- 队列空 :
front == rear - 队列满 :
(rear + 1) % MAXQSIZE == front - 队列长度 :
(rear - front + MAXQSIZE) % MAXQSIZE - 入队条件:队列未满
- 出队条件:队列不为空
通过以上判断条件,可以确保循环队列的正确操作。