重学数据结构:循环队列(C语言)

循环队列的概念

将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。
在这里插入图片描述

循环队列的存储溢出问题(满,空)及解决方案

问题描述:循环队列都会有队列的头指针和尾指针,而且循环队列一般用数组来定义长度,也就是说长度是有限的,头指针一般指向队列的头节点,尾指针一般指向尾元素节点。每次入队的时候,尾指针都是rear++,出队的时候,头指针都是front++。当两指针相遇了,就会发生溢出的问题。如下图d1所示。
在这里插入图片描述
解决方案:

  1. 空一位处理。rear始终指向下一个要插入的位置。
  2. count累计处理。count来计算当前队列长度。(充分利用所有的空间)
  3. 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:90:11:22:33:44:55:66:77:88:9
front:3,rear:20:41:52:63:74:85:96:17:78: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:90:11:22:33:44:55:66:77:88:9
front:3,rear:20:41:52:63:74:85:96:17:78:4
请按任意键继续. . .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值