循环队列复习

由于普通队列出现了假溢出的问题,我们使用循环队列的方式解决这个问题

假溢出:当rear=maxsize时,front为任意下标t(t!=0),此时队列被判定已满,但是在下标t之前的位置,也就是下标小于t的位置理论上还可以存放元素

如何实现循环队列:

循环队列初始形态:rear=front=0

循环队列入队:rear=(rear+1)%maxsize

循环队列出队:front=(front+1)%maxsize

循环队列长度:(rear-front+maxsize)%maxsize  注:这里的front不指向元素

若对于每一块位子都用来存放元素的循环队列,判空判满:

判空:rear=front

判满的话无法判断因为如果你要写rear=front判空的话,因为rear=(rear+1)%maxszie所以队列为满也会出现rear=front

为了解决这个问题,我们提出三种方案:

1,空出一块位置不放元素用来区分队空队满,这样的话

队空:rear=front  队满:(rear+1)%maxsize=front  (为什么写成这个呢,因为之前的话,没有空出一块位置,rear一直指向的都是队列中最后一个元素的下一块位置,我们假设rear一直加front不动,rear加到maxszie-1时,此时再进行入队则为队满,rear=(rear+1)%maxszie,所以此时的rear=0=front因此被判为队空是错误的,而此时我们空出了一个位置,rear指向的位置为队列中的最后一个元素,还是假设rear一直加front不动,当rear加到maxsize-1时判定条件front=(rear+1)%maxszie成立,判定为队满,由于rear指向的为队列中最后一个元素,此时确实为队满,完美解决问题)

2,类型中增设size成员,表示元素个数,删除成功size减一,插入成功size加一,队空状态size=0,队满状态size=maxsize,两种情况都会出现rear=front

3,类型中增设tag数据成员,删除成功tag=0,若导致了front=rear则为队空,插入成功tag=1,若导致了rear=front则为队满

//以下是我写的第一种方法的一些函数,主函数写的并不好,可以自行完善一下 
#include <stdio.h>
#define maxsize 10
typedef struct queue{
	int data[maxsize];
	int front,rear;
}squeue;
squeue p;
//初始化 
void initqueue(squeue &p)
{
	p.front=p.rear=0;
 } 
//判空
bool emptyqueue(squeue p)
{
	if (p.front==p.rear) return true;
	return false;
 } 
//判满
bool manqueue(squeue p)
{
	if(p.front==(p.rear+1)%maxsize) return true;
	return false;
 } 
//入队
bool push(squeue &p,int x)
{
	//先判满
	if(manqueue(p))
	{
		printf("队列已满\n");
		return false;
	 }
	//rear先往后移动一位,然后再插入,这样就可以让rear指向最后一个元素,空出一块位置 
	p.rear=(p.rear+1)%maxsize;
	p.data[p.rear]=x;
	return true; 
}
//出队
bool pop(squeue &p,int &x)
{
	//先判空
	if(emptyqueue(p))
	{
		printf("队列为空\n");
		return false;
	 }
	//由于front指向第一个元素的前一块空位置,所以我们先移动front再删除就可以既能删掉元素又能移动front到删除完之后的第一个元素的前一块空位置
	p.front=(p.front+1)%maxsize; 
	x=p.data[p.front];
	return true;
 } 
int main()
{
	int x,y,l;
	//初始化
	initqueue(p);
	//入队
	while(1)
	{
		printf("输入你要入队的元素值:");
		scanf("%d",&x);
		int j=push(p,x);
		if(j!=0)
		{
			printf("插入了第%d个元素,元素值为%d\n",p.rear,x);
	    }
	    if(j==0) break;
	}
	//出队
	while(l!=9999)
	{
		int k=pop(p,y);
		if(k!=0) printf("删除了队列中第%d个元素,元素值为%d\n",p.front,y);
		if(k==0) break;
		printf("是否继续删除:输入9999结束");
		scanf("%d",&l);
	}	
}

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值