数据结构之队列

 顺序储存和链式储存


基础:结构体,数组,指针。

本文编译环境: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.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值