顺序储存和链式储存
基础:结构体,数组,指针。
本文编译环境:Dev c++ 5.4.0
语言:c
序言:顺序储存这点,关于假溢出的情况就不在讨论,直接讲他的升级版--循环队列,比如一个储存能力为4的队列,头如果分别是:0,1,2,3,那么对应的他的下一个位置就是:1,2,3,0。所以升级版做的事儿就是这个过程,不是再判断队尾是不是最后一个储存单元,而看的是如果头分别是:0,1,2,3,而且尾分别是3,0,1,2的情况,在这里讨论了两种下坐标的处理。
第一个是判断下一个入队位置是哪里,如果尾当前为q,则输入位置是:(q+1)%4,相当于如何0,1,2,3变成1,2,3,0。
第二个是判断当前队列是否满了,如果当前头f分别是0,1,2,3,则队列满的时候其队尾q分别是3,0,1,2,相当于判断(q+1)%4==f是否成立。
解决了上边两个问题,再看下边的代码就容易理解的多。
#include<stdio.h>
#include<stdlib.h>
#define MAXLEN 100
#define datatype char
//结构体的建立
typedef struct
{
datatype data[MAXLEN];//储存空间
int front;//头
int rear;//尾
}Seqlist;//名字
int judge(Seqlist *Lq) //判断队列的状态
{
if(Lq->front==Lq->rear) return 0;//空
else if((Lq->rear+1)%MAXLEN==Lq->front) return 1;//满
else return -1;//其他
}
void Inqueue(Seqlist *Lq,datatype x)
{
if(judge(Lq)==1) printf("队列满");//输出
else
{
Lq->rear=(Lq->rear+1)%MAXLEN;//队尾加一
Lq->data[Lq->rear]=x;//数据输入
}
}
void Outqueue(Seqlist *Lq/*,datatype &x*/)//注释部分为出队的回归
{
if(judge(Lq)==0) printf("队列空");//输出
else
{
//x=Lq->data[Lq->front];
Lq->front++;//队头加一
}
}
void Lookqueue(Seqlist *Lq)//输出所有
{
int i;
for(i=Lq->front+1;i!=(Lq->rear+1)%MAXLEN;i++)
{
printf("%d\n",Lq->data[i]);//输出
}
}
int main()
{
Seqlist *Lq=(Seqlist *)malloc(sizeof(Seqlist));//定义
Lq->front=0;//初始化
Lq->rear=0;//初始化
Inqueue(Lq,1);//入队
Inqueue(Lq,2);//入队
Inqueue(Lq,3);//入队
Inqueue(Lq,4);//入队
Lookqueue(Lq);//输出所有
Outqueue(Lq);//出队
Lookqueue(Lq);//输出所有
return 0;
}
结果
线性链队列:
#include<stdio.h>
#include<stdlib.h>
#define MAXLEN 100
#define datatype char
//结构体的建立
typedef struct Seq
{
datatype data;//储存空间
struct Seq *next;//下一个节点
}Seqlist;//名字
typedef struct
{
Seqlist *front,*rear;//头尾指针
}Link;//名字
//入队
void Inqueue(Link &s,datatype x)
{
Seqlist *Lq=(Seqlist *)malloc(sizeof(Seqlist));//分配空间
Lq->data=x;//传输当前数据
Lq->next=NULL;//初始化当前的下一个节点
if(s.front==NULL) s.front=Lq;//如果队列为空
else s.rear->next=Lq;//不为空放在队尾
s.rear=Lq;//队尾指针重置
}
//出队
void Outqueue(Link &s)//注释部分为出队的回归
{
if(s.front==NULL) printf("队列为空"); //输出错误提示
else
{
Seqlist *Lq=s.front;//媒介储存头指针
s.front=s.front->next;//头指针指向下一个节点
if(s.front==NULL) s.rear=NULL;//如果只有一个元素,则队尾也为空
delete Lq;//删除空间
}
}
void Lookqueue(Link s)
{
Seqlist *Lq=s.front;//媒介
if(s.front==NULL) printf("空的");
else
{
while(Lq!=NULL)
{
printf("%d\n",Lq->data);
Lq=Lq->next;
}
}
}
int main ()
{
Link s;
s.front=NULL;
s.rear=NULL;
Inqueue(s,1);//入队
Inqueue(s,2);//入队
Inqueue(s,3);//入队
Inqueue(s,4);//入队
Lookqueue(s);//查看所有
Outqueue(s);//出队
Lookqueue(s);//查看所有
return 0;
}
结果:
线性链队列的特点是“先进先出”,要注意的部分就是链队输入第一个数据的时候,要让指针首尾都指向第一个数据,而在出队的时候,如果只有一个数据,则队首尾都要重置为空,以及即使回收内存的操作。
这些代码都是跑过的,建议大家还是自己亲手敲一遍加深印象,作者这里也是一字一字敲出来的,要避免眼高手低。
本章的内容有误或者不懂的地方,大家可以私信我,我也会第一时间回复大家的,差不多暑假两个月,复习下这些基本知识,其他的问题也可以问我,就算我不知道的,在能力范围之内的一定竭尽全力为你们解答。我的QQ:932824098.