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