循环队列是指, 队尾指针走到末尾后, 还可以继续从头开始走.
front指针仍然是指向第一个元素的前一个元素, rear指针指向最后一个元素.
下面我们重点讨论一下循环队列如何判断空和满的问题?
我下面判断队列空和满是直接根据q->length
属性来判断, 当q->length
为0,
表示队列为空, 当q->length = maxSize - 1
时, 队列为满. 由于遍历上的原因,
队列的最大长度只能是数组最大长度-1.
#include <stdio.h>
#include <stdlib.h>
struct queue {
int* data;
int front;
int rear;
int maxSize;
int length;
};
typedef struct queue node;
typedef struct queue* link;
// 函数声明
link createQueue (int maxSize);
void printQueue (link q);
int add (link q, int x);
int del (link q);
int main () {
int i;
int maxSize = 10; // 队列的最大长度
link qhead = createQueue(maxSize);
// 初始队列信息
printQueue(qhead);
// 基本入队测试
for (i=1; i<=10; i++) {
add(qhead, i * 2);
}
printQueue(qhead);
// 基本出队测试
del(qhead);
del(qhead);
del(qhead);
del(qhead);
printQueue(qhead);
// 循环入队测试
add(qhead, 100);
add(qhead, 200);
add(qhead, 300);
add(qhead, 400);
add(qhead, 500);
printQueue(qhead);
return 0;
}
// 创建空队列
link createQueue (int maxSize) {
link q;
q = (node*)malloc(sizeof(node));
q->data = (int*)malloc(sizeof(int) * maxSize);
q->front = -1;
q->rear = -1;
q->length = 0;
q->maxSize = maxSize;
return q;
}
// 打印
void printQueue (link q) {
int i;
printf("当前队列的信息如下:
");
printf("front = %d
", q->front);
printf("rear = %d
", q->rear);
printf("length = %d
", q->length);
printf("maxSize = %d
", q->maxSize);
// 打印队列中的数据
if (q->length == 0) {
printf("当前队列中没有数据
");
} else {
printf("队列中的数据如下:
");
i = q->front;
while (i != q->rear) {
i = (i + 1) % q->maxSize;
printf("%d %d
", i, q->data[i]);
}
}
printf("
");
}
// 入队
int add (link q, int x) {
if (q->length == q->maxSize -1 ) {
printf("队列已满, 不能入队
");
return 0;
}
q->rear = (q->rear + 1) % q->maxSize;
q->data[q->rear] = x;
q->length++;
return 1;
}
// 出队
// 错误返回0, 正确返回被出队元素的值
int del (link q) {
if (q->length == 0) {
printf("队列为空, 不能出队
");
return 0;
}
q->front = (q->front + 1) % q->maxSize;
q->length--;
return q->data[q->front];
}