//循环队列--------------------------------------------------------------------------
//符合先进先出
//空间大小时固定的
//循环队列要多开一个空间,即k+1个空间,才能判断是否为空
//创建循环数列结构体
typedef struct
{
int* a;
int front;//队头(数组下标)
int tail;//队尾(数组下标)
int k;//空间大小
}MyCircullarQueque;
//初始化
MyCircullarQueque* MyCircullarQuequeCreate(int k)
{
//创建循环队列变量
MyCircullarQueque* cq = (MyCircullarQueque*)malloc(sizeof(MyCircullarQueque));
//初始化
//给a开辟k+1个空间
cq->a = (int*)malloc(sizeof(int) * (k + 1));
//队头队尾下标都指向第一个元素
cq->front = cq->tail = 0;
//确定空间大小
cq->k = k;
}
//入队列
bool MyCircullarQuequeEnQueque(MyCircullarQueque* obj, int val)
{
//判断是否满了
if (MyCircullarQuequeIsFull(obj))
{
return false;
}
//没满,在tail的位置入队列
obj->a[obj->tail] = val;
++obj->tail;
//如果队尾值到了k+1(即数组最后位置)
//则让tail取模k+1,实现数组队列循环
obj->tail %= (obj->k + 1);
return true;
}
//出队列
bool MyCircullarQuequeDeQueque(MyCircullarQueque* obj)
{
//判断是否为空
if (MyCircullarQuequeIsEmpty(obj))
{
return false;
}
//不为空
//front往后移,就达到删除的目的
++obj->front;
//如果队头值到了k+1(即数组最后位置)
//则让front取模k+1,实现数组队列循环
obj->front %= (obj->k + 1);
return true;
}
//取队头数据
int MyCircullarQuequeFront(MyCircullarQueque* obj)
{
//判断是否为空
if (MyCircullarQuequeIsEmpty(obj))
{
return -1;
}
//返回front下标所在的元素
return obj->a[obj->front];
}
//取队尾数据
int MyCircullarQuequeRear(MyCircullarQueque* obj)
{
//判断是否为空
if (MyCircullarQuequeIsEmpty(obj))
{
return -1;
}
//取队尾,则要取tail-1下标所在的元素
//如果tail在0下标所在位置
if (obj->tail == 0)
{
//返回最后一个元素
return obj->a[obj->k];
}
else
return obj->a[obj->tail - 1];
//另外一种写法
//用tail+k取模k+1,得到的值便为tail-1下标所在的元素
int tail_i = (obj->tail + obj->k) % (obj->k + 1);
return obj->a[tail_i];
}
//是否为空
bool MyCircullarQuequeIsEmpty(MyCircullarQueque* obj)
{
//因为开辟了k+1个空间,如果front==tail,说明队列为空
return obj->front == obj->tail;
}
//是否满了
bool MyCircullarQuequeIsFull(MyCircullarQueque* obj)
{
//因为是循环队列,又开辟了k+1个空间,当tail循环时,
// tail+1的下标位置取模整个空间所有元素个数,所得到的位置与front相同,
// 说明已存满
//
return (obj->tail + 1) % (obj->k + 1) == obj->front;
}
//释放
void MyCircullarQuequefree(MyCircullarQueque* obj)
{
//开辟了两次空间,释放两次
free(obj->a);
free(obj);
}