概念
循环队列就是将队列存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间,供队列循环使用。在循环队列结构中,当存储空间的最后一个位置已被使用而再要进入队运算时,只需要存储空间的第一个位置空闲,便可将元素加入到第一个位置,即将存储空间的第一个位置作为队尾。 循环队列可以更简单防止伪溢出的发生,但队列大小是固定的。
在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件是front=rear,而队列判满的条件是front=(rear+1)%MaxSize。
#include <iostream>
using namespace std;
#define ElemType int
#define MaxSize 100
typedef struct {
ElemType date[MaxSize];
//队头指针和队尾指针,队尾指针插入队尾元素的后一位置
int front, rear;
//int len 可以使用len来简化判断是否空或满
} SqQueue;
void InitQueue(SqQueue &s) {
s.front = s.rear = 0;
}
bool IsEmpty(SqQueue s) {
return s.rear == s.front;
}
//此处我们牺牲一个单元格的位置,当队尾指针的的下一个单元格的位置指向对头,说明已满
bool IsFull(SqQueue s) {
return (s.rear + 1) % MaxSize == s.front;
}
bool EnQueue(SqQueue &s, ElemType e) {
if (IsFull(s))
return false;
s.date[s.rear];
s.rear = (s.rear + 1) % MaxSize;
return true;
}
bool DeQueue(SqQueue &s, ElemType &e) {
if (IsEmpty(s))
return false;
e = s.date[s.front];
s.front = (s.front + 1) % MaxSize;
return true;
}
bool Peek(SqQueue s, ElemType &e) {
if (IsEmpty(s))
return false;
e = s.date[s.front];
return false;
}
bool Pop(SqQueue &s, ElemType &e) {
if (IsEmpty(s))
return false;
e = s.date[s.front];
s.front = (s.front + 1) % MaxSize;
return true;
}
int Length(SqQueue s) {
return (s.rear - s.front + MaxSize) % MaxSize;
}