为解决顺序队列存在的严重问题,伟大的先驱们又发明了一种可以循环使用的队列以解决内存空间浪费的问题–环形队列。
环形队列的物理存储结构与顺序队列并没有什么差别,但是逻辑存储结构的改变使之截然不同。
充分地使用数组中的存储空间,把数组的前端和后端连接起来,形成一个环形的顺序表,即把存储队列元素的表从逻辑上看成一个环。
typedef struct
{
ElemType data[MaxSize];
int front,rear;
} SqQueue;
环形队列四要素:
队空:rear==front;
队满:(rear+1)%MaxSize == front;
进栈:rear = (rear+1)%MaxSize;data[rear] = e;
出栈:front = (front+1)%MaxSize;e = data[front];
由此可以看出环形队列只能存储MaxSize-1个元素,front指向的元素为无效元素。
环形队列操作函数:
①初始化队列:
void InitQueue(SqQueue *&q)
{
q = (* SqQueue)malloc(sizeof(SqQueue));
q->front = q->rear = 0;
}
②销毁队列:
void DestroyQueue(SqQueue *&q)
{
free(s);
}
③队列判空:
bool EmptyQueue(SqQueue *&q)
{
return (q->rear == q->front);
}
④进队列EnQueue
bool EnQueue(SqQueue *&q,ElemType e)
{
if((q->rear+1)%MaxSize==q->front)
return false;
q->rear = (q->rear+1)%MaxSize;
q->data[q->rear] = e;
return true;
}
⑤出队列DeQueue
bool DeQueue(SqQueue *&q,ElemType &e)
{
if(q->front == q->rear)
return false;
q->front = (q->front+1)%MaxSize;
e = q->data[q->front];
return true;
}
延伸:对于已知front,rear,count(队列中元素个数)三者知其二,都可求出另外一个。(默认MaxSize已知)
已知front,rear,求元素个数count
count = (rear-front+MaxSize)%MaxSize
已知front,count,求尾指针rear
rear = (front+count)%MaxSize
已知count,rear,求头指针front
front = (rear-count+MaxSize)%MaxSize
通过只记录count和front,rear其中一个也可构成环形队列
typedef struct
{
ElemType data[MaxSize];
int rear,count;
}SqQueue;
四要素:
队空:count == 0;
队满:count == MaxSize;
进队:rear = (rear+1)%MaxSize;data[rear] = e;
出队:front = (front+1)%MaxSize;e = data[front]; (front可以根据count,rear求出)
特点:可以存储MaxSize个元素