% MaxSize 消除假溢出;长度 (rear − front + MaxSize) % MaxSize,队满(牺牲一单元)(rear+1)%MaxSize == front。队列是只允许在一端(队尾)插入,另一端(队头)删除的线性表。
普通顺序队列中,front 和 rear 不断后移,即使前面有空位也无法使用。
将数组首尾相连,形成逻辑上的环。
#define MaxSize 50
typedef struct {
ElemType data[MaxSize];
int front; // 队头指针
int rear; // 队尾指针
} SqQueue;
void InitQueue(SqQueue *Q) {
Q->front = 0;
Q->rear = 0;
}
bool QueueEmpty(SqQueue Q) {
return (Q.front == Q.rear);
}
bool EnQueue(SqQueue *Q, ElemType x) {
if ((Q->rear + 1) % MaxSize == Q->front) // 队满
return false;
Q->data[Q->rear] = x;
Q->rear = (Q->rear + 1) % MaxSize;
return true;
}
bool DeQueue(SqQueue *Q, ElemType *x) {
if (Q->front == Q->rear) // 队空
return false;
*x = Q->data[Q->front];
Q->front = (Q->front + 1) % MaxSize;
return true;
}
int QueueLength(SqQueue Q) {
return (Q.rear - Q.front + MaxSize) % MaxSize;
}
typedef struct {
ElemType data[MaxSize];
int front, rear, size;
} SqQueue;
// 队空:size == 0
// 队满:size == MaxSize
typedef struct {
ElemType data[MaxSize];
int front, rear, tag;
} SqQueue;
// 最近操作:tag=1 为入队,tag=0 为出队
// 队空:front == rear 且 tag == 0
// 队满:front == rear 且 tag == 1
typedef struct LinkNode {
ElemType data;
struct LinkNode *next;
} LinkNode;
typedef struct {
LinkNode *front, *rear; // 队头队尾指针
} LinkQueue;
void InitQueue(LinkQueue *Q) {
Q->front = Q->rear = (LinkNode *)malloc(sizeof(LinkNode));
Q->front->next = NULL;
}
bool QueueEmpty(LinkQueue Q) {
return (Q.front == Q.rear);
}
void EnQueue(LinkQueue *Q, ElemType x) {
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = x;
s->next = NULL;
Q->rear->next = s;
Q->rear = s;
}
bool DeQueue(LinkQueue *Q, ElemType *x) {
if (Q->front == Q->rear) return false;
LinkNode *p = Q->front->next;
*x = p->data;
Q->front->next = p->next;
if (Q->rear == p) // 若只有一个元素
Q->rear = Q->front;
free(p);
return true;
}
rear 需要指向头结点。void DestroyQueue(LinkQueue *Q) {
while (Q->front != NULL) {
LinkNode *p = Q->front;
Q->front = Q->front->next;
free(p);
}
}
| 特性 | 循环队列 | 链队列 |
|---|---|---|
| 存储方式 | 连续 | 离散 |
| 队满判断 | $ (rear+1)\%MaxSize==front $ | 无(动态分配) |
| 空间 | 固定 | 动态 |
| 入队出队 | O(1) | O(1) |
$MaxSize = 6$,初始 $front = rear = 0$
| 操作 | front | rear | 队列内容 |
|---|---|---|---|
| EnQueue(A) | 0 | 1 | [A] |
| EnQueue(B) | 0 | 2 | [A,B] |
| EnQueue(C) | 0 | 3 | [A,B,C] |
| DeQueue() | 1 | 3 | [B,C] |
| DeQueue() | 2 | 3 | [C] |
| EnQueue(D) | 2 | 4 | [C,D] |
| EnQueue(E) | 2 | 5 | [C,D,E] |
| EnQueue(F) | 2 | 0 | [C,D,E,F](循环!) |
此时 $ (rear+1)\%6 = 1 \neq front=2 $,未满。再入队 G:$ (0+1)\%6 = 1 \neq 2 $,入队后 $rear=1$。再入队:$ (1+1)\%6 = 2 == front $ → 队满!
$front = 3,\; rear = 7,\; MaxSize = 8$ → 长度 $ = (7 - 3 + 8) \% 8 = 4$。
% MaxSize。MaxSize-1。rear - front。↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。