文章目录
循环队列的概念
将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。
循环队列的存储溢出问题(满,空)及解决方案
问题描述:循环队列都会有队列的头指针和尾指针,而且循环队列一般用数组来定义长度,也就是说长度是有限的,头指针一般指向队列的头节点,尾指针一般指向尾元素节点。每次入队的时候,尾指针都是rear++,出队的时候,头指针都是front++。当两指针相遇了,就会发生溢出的问题。如下图d1所示。
解决方案:
- 空一位处理。rear始终指向下一个要插入的位置。
- count累计处理。count来计算当前队列长度。(充分利用所有的空间)
- flag标志位处理。0/1来判断队列是否满队。(充分利用所有的空间)
循环队列的代码实现(空一位处理)
typedef struct CLNode
{
int data[MaxSize];
int rear,front;
}CLNode, *CycleQueue;
void InitQueue(CycleQueue &L)
{
L=(CycleQueue)malloc(sizeof(CLNode));
L->front=L->rear=0;
}
bool IsQueueEmpty(CycleQueue &L)
{
if(L->front==L->rear)
return true;
else
return false;
}
bool IsQueueFull(CycleQueue &L)
{
if((L->rear+1)%MaxSize==L->front)
return true;
else
return false;
}
bool EnQueue(CycleQueue &L,int data)
{
if(IsQueueFull(L))return false;
L->data[L->rear]=data;
L->rear=(L->rear+1)%MaxSize;
return true;
}
bool DeQueue(CycleQueue &L,int &data)
{
if(IsQueueEmpty(L))return false;
data=L->data[L->front];
L->front=(L->front+1)%MaxSize;
return true;
}
void PrintQueue(CycleQueue L)
{
int acc=L->front;
int i=0;
printf("front:%d,rear:%d\n",L->front,L->rear);
while(acc!=L->rear)
{
printf("第%d位:%d\t",i,L->data[acc]);
acc=(acc+1)%MaxSize;
i++;
}
printf("\n");
}
循环队列的代码实现测试(空一位处理)
void InitQueueData(CycleQueue &L)
{
int a[]={1,2,3,4,5,6,7,8,9,10};
int length=sizeof(a)/sizeof(a[0]);
for(int i=0;i<length;i++)
{
EnQueue(L,a[i]);
}
}
int main(int argc, char* argv[])
{
CycleQueue L;
InitQueue(L);
InitQueueData(L);
PrintQueue(L);
int data;
DeQueue(L,data);
DeQueue(L,data);
DeQueue(L,data);
EnQueue(L,rand()%10);
EnQueue(L,rand()%10);
EnQueue(L,rand()%10);
PrintQueue(L);
return 0;
}
循环队列的代码实现测试结果(空一位处理)
front:0,rear:9
第0位:1 第1位:2 第2位:3 第3位:4 第4位:5 第5位:6 第6位:7 第7位:8 第8位:9
front:3,rear:2
第0位:4 第1位:5 第2位:6 第3位:7 第4位:8 第5位:9 第6位:1 第7位:7 第8位:4
请按任意键继续. . .
循环队列的代码实现(flag标志处理)
typedef struct CLNode
{
int data[MaxSize];
int rear,front;
int flag; //增加代码
}CLNode, *CycleQueue;
bool IsQueueEmpty(CycleQueue &L)
{
if(L->front==L->rear&&L->flag==false) //修改的代码
return true;
else
return false;
}
bool IsQueueFull(CycleQueue &L)
{
if((L->rear+1)%MaxSize==L->front&&L->flag==true)//修改的代码
return true;
else
return false;
}
bool EnQueue(CycleQueue &L,int data)
{
if(IsQueueFull(L))return false;
L->data[L->rear]=data;
L->rear=(L->rear+1)%MaxSize;
L->flag=true;//增加代码
return true;
}
bool DeQueue(CycleQueue &L,int &data)
{
if(IsQueueEmpty(L))return false;
data=L->data[L->front];
L->front=(L->front+1)%MaxSize;
L->flag=false;//增加代码
return true;
}
循环队列的代码实现测试(flag标志处理)
void InitQueueData(CycleQueue &L)
{
int a[]={1,2,3,4,5,6,7,8,9,10};
int length=sizeof(a)/sizeof(a[0]);
for(int i=0;i<length;i++)
{
EnQueue(L,a[i]);
}
}
int main(int argc, char* argv[])
{
CycleQueue L;
InitQueue(L);
InitQueueData(L);
PrintQueue(L);
int data;
DeQueue(L,data);
DeQueue(L,data);
DeQueue(L,data);
EnQueue(L,rand()%10);
EnQueue(L,rand()%10);
EnQueue(L,rand()%10);
PrintQueue(L);
return 0;
}
循环队列的代码实现测试结果(flag标志处理)
front:0,rear:9
第0位:1 第1位:2 第2位:3 第3位:4 第4位:5 第5位:6 第6位:7 第7位:8 第8位:9
front:3,rear:2
第0位:4 第1位:5 第2位:6 第3位:7 第4位:8 第5位:9 第6位:1 第7位:7 第8位:4
请按任意键继续. . .