前言
我们这里一共三个方法,通过是否舍弃空间来实现队列空满的判断。
队列的数据结构
const int MaxSize=10;
typedef struct
{
int data[MaxSize];
int front,rear;
}Queue;
front指向第一个元素。
rear指向下一个为空的,可插入的位置。
初始化
bool initqueue(Queue &q){
q.front=q.rear=0;
return true;
}
初始化时,令front和rear都指向第一个位置。
此时,队列为空,所以我们自然想到一个判断队列为空的条件:
q.front == q.rear
不知掉是否会有疑问?为什们不是像初始化那样等于0?
因为队列的特性,它是FIFO(先进先出)的,最后出队列的位置
不一定是第一个位置(往往也不是第一个位置)。
一、舍弃空间
判断队列为满的条件:
((q.rear+1)%MaxSize)==0 //取余是因为是循环队列
意思就是最后一个空位置的下一个位置就是队列的第一个位置(循环)
如上图,此时的循环队列就是判断为满的条件。
但是我们为什们就必须要舍弃呢?
假设我们不舍弃,判断为满的条件是:
q.front==q.rear
是不是很眼熟,因为它和判断队列为空的条件重合了。
所以在没有其他条件的情况下,我们只有通过舍弃最后一个位置来
判断循环队列为满了。
二、不舍弃空间
不舍弃空间的话,我们有两种方法。
1.计数器
通过在队列的数据结构中添加一个计数位来实现判断队列的空满。
const int MaxSize=10;
typedef struct
{
int data[MaxSize];
int front,rear;
int count;
}Queue;
在初始化时,也要微调:
bool initqueue(Queue &q){
q.front=q.rear=0;
q.count=0;
return true;
}
令计数器(count)等于0。
显而易见的,此时的条件:
队列满:count==MaxSize。
队列空:count ==0。
2.设置标志位
我们在程序设计时,遇到此时的条件不能直接判断时,通常的做法就是添加标志位。
const int MaxSize=10;
typedef struct
{
int data[MaxSize];
int front,rear;
int sign;
}Queue;
将 int 类型的sign作为标志位。
成功插入就:sign=1。
成功删除就:sign=0。
初始化:
bool initqueue(Queue &q){
q.front=q.rear=0;
q.sign=0;
return true;
}
因为此时队列为空,sign就为0。
之前讲到,不舍弃空间的话,队满的条件和队空的条件重合了。
即:q.front == q.rear。
现在有了标志位,就能将其分开:
队满: q.front == q.rear && sign == 1;
队空: q.front == q.rear && sign==0;