利用数组实现队列(超级简单)

数组实现队列

我们之前既然已经说过可以用链表实现队列,那么我也知道队列就是一种表,那么自然的,也可以用数组实现队列,上代码:后讲解

/*队列的数组实现*/
/*头文件*/ 
#include<stdio.h>
#include<stdlib.h>
#define error(str) fprintf(stderr,"%s",str),exit(1)//自定义报错信息
typedef struct node
{
	int *a;
	int size;//size表示长度 
	int fornt;
	int rear;
}p; 
/*函数区*/
p* creat();//创建及初始化 
int isempty(p* q);//判断队列是否为空
int isfull(p* q);//判断是否为满 
void init(p* q,int n);//入队
void outit(p* q);//出队
void print(p* q);//遍历输出
/*主函数*/ 
int main()
{
	int i;
	p* q=creat();
	for(i=0;i<5;i++)
		init(q,i);
	printf("\n遍历\n");
	print(q);
	for(i=0;i<2;i++)
		outit(q);
	printf("\nafter out\n");
	print(q);
	return 0;
} 
/*函数实现*/ 
p* creat()
{
	p* q=(p*)malloc(sizeof(p));
	q->a=(int*)malloc(sizeof(int)*5);//开辟五个元素的空间
	q->fornt=0;//整体进行初始化 
	q->rear=0;
	q->size=0; 
}
int isempty(p* q)
{
	return q->size==0;//为0则为空返回1 
}
int isfull(p* q)
{
	return q->size==5;//为5则满,返回1否则返回0。 
}
void init(p* q,int n)
{ 
	if(isfull(q))
		error("is full");
	q->rear%=5;
	q->a[q->rear++]=n;//实现完之后自加 这里的前点不变 
	q->size+=1;//这里入队的情况应该都考虑到了。 
} 
void outit(p* q)
{
	if(isempty(q))
		error("is empty");
	q->fornt=(q->fornt+1)%5;//对fornt进行变化 ,最后用fornt和rear进行遍历。
	q->size-=1; 
} 
void print(p* q)
{
	if(q->size==0)
		error("is empty");
	if(q->size==1)
		printf("%d",q->a[q->rear-1]); 
	int i=q->fornt;//front=0;
	do
	{
		printf("%d ",q->a[i]);
		i=(i+1)%5;
	}while(i!=(q->rear-1));
	printf("%d ",q->a[i]);
} 

首先呢,这一段代码是博主没有观望网上或书上的代码,直接根据队列的定义纯自造成的。😂😂
之后,我与网上大致对比了一下,我jio的我的复杂度还可以,这应该是目前的最简形式了😂。为了这段代码,我霍霍了一页纸如下↓
在这里插入图片描述
嗯,因为是草稿,所以字不好看并且很乱就很科学😂哈哈,不多废话了。

  1. 首先呢,我想到队列这种结构,利用数组的话,一定只能存有限个,而且如果我们要不断的切换数组元素的复杂度会巨大,每一种切换都需要一个for循环因此…我决定用结构体里的三个整形数据来实现整个数据的流动,我相信这应该也是大多数教程里面的,因为没有人会傻到写n个for循环实现数据流动。这里我们可以看到,我的结构体中有三个整形数据,以及一个整形数组。这个整形数组就是我们需要容纳数据的地方,那三个数据分别为队头的下标,队尾的下标,以及所容纳的数量。
  2. 我们还是先做好准备工作,将头文件,自定义错误类型,函数区,划分清楚。然后我们一个一个来实现。因为引入了size这个整形数据因此判断,队列为空或为满就很容易,直接return size==n便可,这也是我引入这个数据的主要原因,多分配一个整形的空间,节省了一系列复杂操作。
  3. 实现入队,这里我采用的是入队即自加的方法,也就是说,入队一个,他的索引便往后走一格,类似于指针,便代替了指针的功效。
  4. 循环数组:这是该算法中心思想,必须是循环数组才可以实现队列,因为我们随着入队出队的各种操作,(比如我们先入队五个,出队两个,这样就会导致,我们的头索引为2,尾索引为4这样的话,我们要继续入队,就要将尾索引变为0因此便有了我函数中的取模操作,他可以使我们的数组变相的被视为一个循环数组),并且我们在数据流动的时候,即出队入队的时候,只是对索引进行操作,根据索引往数组中添加数据,这样我们的数组他唯一的作用就是容纳空间了,这样我们便把这两个整形数据变相的化为了指针,怎么样,这个想法不错吧😏要是不理解的小伙伴,可以把代码一步一步在脑子里转一下,就很容易理解了。
  5. 出栈入栈解决之后,我碰到的难题便是遍历输出了,这里我同样想到了循环数组的方法,但是while循环不能一次全部输出我们需要的,这倒是一个遗憾,我想了一个小时该怎么改,能让他一个while循环包含所有工作,但是结果不太理想,因此我只好在整个while外面加上一个printf了,不过不用担心,size为0打的时候他还会输出,因为我已经加了if判断。嘿嘿。整体来看,还算简单。建议小伙伴们自己写,如果觉得复杂的可以采用博主的方法。但还是自己多想比较好。好了今天到这里了,这玩意让我有些累😂

alright good night.

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值