三图的顺序存储表示和实现讲解.docx
《三图的顺序存储表示和实现讲解.docx》由会员分享,可在线阅读,更多相关《三图的顺序存储表示和实现讲解.docx(26页珍藏版)》请在冰豆网上搜索。
![三图的顺序存储表示和实现讲解.docx](https://file1.bdocx.com/fileroot1/2022-12/8/c5c0b1bc-e26e-4465-9300-d64ead1ad513/c5c0b1bc-e26e-4465-9300-d64ead1ad5131.gif)
三图的顺序存储表示和实现讲解
学校代码:
学号:
数据结构实验报告
题目:
图的顺序存储表示和实现
学生姓名:
学院:
班级:
指导教师:
年月
一、实验目的
掌握图的顺序存储表示和实现
二、实验内容
C1.h
//c1.h(程序名)
#include
#include
#include//malloc()等
#include//INT_MAX等
#include//EOF(=^Z或F6),NULL
#include//atoi()
#include//eof()
#include//floor(),ceil(),abs()
#include//exit()
#include//cout,cin
//函数结果状态代码
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
//#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedefintStatus;//Status是函数的类型,其值是函数结果状态代码,如OK等
typedefintBoolean;//Boolean是布尔类型,其值是TRUE或FALSE
c3-2.h
//c3-2.h单链队列--队列的链式存储结构
typedefstructQNode
{
QElemTypedata;
QNode*next;
}*QueuePtr;
structLinkQueue
{
QueuePtrfront,rear;//队头、队尾指针
};
C7-1.h
//c7-1.h图的数组(邻接矩阵)存储表示
#defineINFINITYINT_MAX//用整型最大值代替∞
#defineMAX_VERTEX_NUM20//最大顶点个数
enumGraphKind{DG,DN,AG,AN};//{有向图,有向网,无向图,无向网}
typedefstruct
{
VRTypeadj;//顶点关系类型。
对无权图,用1(是)或0(否)表示相邻否;
//对带权图,则为权值类型
InfoType*info;//该弧相关信息的指针(可无)
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
structMGraph
{
VertexTypevexs[MAX_VERTEX_NUM];//顶点向量
AdjMatrixarcs;//邻接矩阵
intvexnum,arcnum;//图的当前顶点数和弧数
GraphKindkind;//图的种类标志
};
Bo3-2.cpp
//bo3-2.cpp链队列(存储结构由c3-2.h定义)的基本操作(9个)
StatusInitQueue(LinkQueue&Q)
{//构造一个空队列Q
if(!
(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))
exit(OVERFLOW);
Q.front->next=NULL;
returnOK;
}
StatusDestroyQueue(LinkQueue&Q)
{//销毁队列Q(无论空否均可)
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
returnOK;
}
StatusClearQueue(LinkQueue&Q)
{//将Q清为空队列
QueuePtrp,q;
Q.rear=Q.front;
p=Q.front->next;
Q.front->next=NULL;
while(p)
{
q=p;
p=p->next;
free(q);
}
returnOK;
}
StatusQueueEmpty(LinkQueueQ)
{//若Q为空队列,则返回TRUE,否则返回FALSE
if(Q.front==Q.rear)
returnTRUE;
else
returnFALSE;
}
intQueueLength(LinkQueueQ)
{//求队列的长度
inti=0;
QueuePtrp;
p=Q.front;
while(Q.rear!
=p)
{
i++;
p=p->next;
}
returni;
}
StatusGetHead(LinkQueueQ,QElemType&e)
{//若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
QueuePtrp;
if(Q.front==Q.rear)
returnERROR;
p=Q.front->next;
e=p->data;
returnOK;
}
StatusEnQueue(LinkQueue&Q,QElemTypee)
{//插入元素e为Q的新的队尾元素
QueuePtrp;
if(!
(p=(QueuePtr)malloc(sizeof(QNode))))//存储分配失败
exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returnOK;
}
StatusDeQueue(LinkQueue&Q,QElemType&e)
{//若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR
QueuePtrp;
if(Q.front==Q.rear)
returnERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
returnOK;
}
StatusQueueTraverse(LinkQueueQ,void(*vi)(QElemType))
{//从队头到队尾依次对队列Q中每个元素调用函数vi()。
一旦vi失败,则操作失败
QueuePtrp;
p=Q.front->next;
while(p)
{
vi(p->data);
p=p->next;
}
printf("\n");
returnOK;
}
Bo7-1.cpp
//bo7-1.cpp图的数组(邻接矩阵)存储(存储结构由c7-1.h定义)的基本操作(20个)
intLocateVex(MGraphG,VertexTypeu)
{//初始条件:
图G存在,u和G中顶点有相同特征
//操作结果:
若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
inti;
for(i=0;iif(strcmp(u,G.vexs[i])==0)
returni;
return-1;
}
StatusCreateFAG(MGraph&G)
{//采用数组(邻接矩阵)表示法,由文件构造没有相关信息的无向图G
inti,j,k;
charfilename[13];
VertexTypeva,vb;
FILE*graphlist;
printf("请输入数据文件名(f7-1.dat):
");
scanf("%s",filename);
graphlist=fopen(filename,"r");
fscanf(graphlist,"%d",&G.vexnum);
fscanf(graphlist,"%d",&G.arcnum);
for(i=0;ifscanf(graphlist,"%s",G.vexs[i]);
for(i=0;ifor(j=0;j{
G.arcs[i][j].adj=0;//图
G.arcs[i][j].info=NULL;//没有相关信息
}
for(k=0;k{
fscanf(graphlist,"%s%s",va,vb);
i=LocateVex(G,va);
j=LocateVex(G,vb);
G.arcs[i][j].adj=G.arcs[j][i].adj=1;//无向图
}
fclose(graphlist);
G.kind=AG;
returnOK;
}
StatusCreateDG(MGraph&G)
{//采用数组(邻接矩阵)表示法,构造有向图G
inti,j,k,l,IncInfo;
chars[MAX_INFO],*info;
VertexTypeva,vb;
printf("请输入有向图G的顶点数,弧数,弧是否含其它信息(是:
1,否:
0):
");
scanf("%d,%d,%d",&G.vexnum,&G.arcnum,&IncInfo);
printf("请输入%d个顶点的值(<%d个字符):
\n",G.vexnum,MAX_NAME);
for(i=0;iscanf("%s",G.vexs[i]);
for(i=0;ifor(j=0;j{
G.arcs[i][j].adj=0;//图
G.arcs[i][j].info=NULL;
}
printf("请输入%d条弧的弧尾弧头(以空格作为间隔):
\n",G.arcnum);
for(k=0;k{
scanf("%s%s%*c",va,vb);//%*c吃掉回车符
i=LocateVex(G,va);
j=LocateVex(G,vb);
G.arcs[i][j].adj=1;//有向图
if(IncInfo)
{
printf("请输入该弧的相关信息(<%d个字符):
",MAX_INFO);
gets(s);
l=strlen(s);
if(l)
{
info=(char*)malloc((l+1)*sizeof(char));
strcpy(info,s);
G.arcs[i][j].info=info;//有向
}
}
}
G.kind=DG;
returnOK;
}
StatusCreateDN(MGraph&G)
{//采用数组(邻接矩阵)表示法,构造有向网G
inti,j,k,w,IncInfo;
chars[MAX_INFO],*info;
VertexTypeva,vb;
printf("请输入有向网G的顶点数,弧数,弧是否含其它信息(是:
1,否:
0):
");
scanf("%d,%d,%d",&G.vexnum,&G.arcnum,&IncInfo);
printf("请输入%d个顶点的值(<%d个字符):
\n",G.vexnum,MAX_NAME);
for(i=0;iscanf("%s",G.vexs[i]);
for(i=0;ifor(j=0;j{
G.arcs[i][j].adj=INFINITY;//网
G.arcs[i][j].info=NULL;
}
printf("请输入%d条弧的弧尾弧头权值(以空格作为间隔):
\n",G.arcnum);
for(k=0;k{
scanf("%s%s%d%*c",va,vb,&w);//%*c吃掉回车符
i=LocateVex(G,va);
j=LocateVex(G,vb);
G.arcs[i][j].adj=w;//有向网
if(IncInfo)
{
printf("请输入该弧的相关信息(<%d个字符):
",MAX_INFO);
gets(s);
w=strlen(s);
if(w)
{
info=(char*)malloc((w+1)*sizeof(char));
strcpy(info,s);
G.arcs[i][j].info=info;//有向
}
}
}
G.kind=DN;
returnOK;
}
StatusCreateAG(MGraph&G)
{//采用数组(邻接矩阵)表示法,构造无向图G
inti,j,k,l,IncInfo;
chars[MAX_INFO],*info;
VertexTypeva,vb;
printf("请输入无向图G的顶点数,边数,边是否含其它信息(是:
1,否:
0):
");
scanf("%d,%d,%d",&G.vexnum,&G.arcnum,&IncInfo);
printf("请输入%d个顶点的值(<%d个字符):
\n",G.vexnum,MAX_NAME);
for(i=0;iscanf("%s",G.vexs[i]);
for(i=0;ifor(j=0;j{
G.arcs[i][j].adj=0;//图
G.arcs[i][j].info=NULL;
}
printf("请输入%d条边的顶点1顶点2(以空格作为间隔):
\n",G.arcnum);
for(k=0;k{
scanf("%s%s%*c",va,vb);//%*c吃掉回车符
i=LocateVex(G,va);
j=LocateVex(G,vb);
G.arcs[i][j].adj=G.arcs[j][i].adj=1;//无向图
if(IncInfo)
{
printf("请输入该边的相关信息(<%d个字符):
",MAX_INFO);
gets(s);
l=strlen(s);
if(l)
{
info=(char*)malloc((l+1)*sizeof(char));
strcpy(info,s);
G.arcs[i][j].info=G.arcs[j][i].info=info;//无向
}
}
}
G.kind=AG;
returnOK;
}
StatusCreateAN(MGraph&G)
{//采用数组(邻接矩阵)表示法,构造无向网G。
算法7.2
inti,j,k,w,IncInfo;
chars[MAX_INFO],*info;
VertexTypeva,vb;
printf("请输入无向网G的顶点数,边数,边是否含其它信息(是:
1,否:
0):
");
scanf("%d,%d,%d",&G.vexnum,&G.arcnum,&IncInfo);
printf("请输入%d个顶点的值(<%d个字符):
\n",G.vexnum,MAX_NAME);
for(i=0;iscanf("%s",G.vexs[i]);
for(i=0;ifor(j=0;j{
G.arcs[i][j].adj=INFINITY;//网
G.arcs[i][j].info=NULL;
}
printf("请输入%d条边的顶点1顶点2权值(以空格作为间隔):
\n",G.arcnum);
for(k=0;k{
scanf("%s%s%d%*c",va,vb,&w);//%*c吃掉回车符
i=LocateVex(G,va);
j=LocateVex(G,vb);
G.arcs[i][j].adj=G.arcs[j][i].adj=w;//无向
if(IncInfo)
{
printf("请输入该边的相关信息(<%d个字符):
",MAX_INFO);
gets(s);
w=strlen(s);
if(w)
{
info=(char*)malloc((w+1)*sizeof(char));
strcpy(info,s);
G.arcs[i][j].info=G.arcs[j][i].info=info;//无向
}
}
}
G.kind=AN;
returnOK;
}
StatusCreateGraph(MGraph&G)
{//采用数组(邻接矩阵)表示法,构造图G。
算法7.1
printf("请输入图G的类型(有向图:
0,有向网:
1,无向图:
2,无向网:
3):
");
scanf("%d",&G.kind);
switch(G.kind)
{
caseDG:
returnCreateDG(G);//构造有向图
caseDN:
returnCreateDN(G);//构造有向网
caseAG:
returnCreateAG(G);//构造无向图
caseAN:
returnCreateAN(G);//构造无向网
default:
returnERROR;
}
}
voidDestroyGraph(MGraph&G)
{//初始条件:
图G存在。
操作结果:
销毁图G
inti,j;
if(G.kind<2)//有向
for(i=0;i{
for(j=0;jif(G.arcs[i][j].adj==1&&G.kind==0||G.arcs[i][j].adj!
=INFINITY&&G.kind==1)//有向图的弧||有向网的弧
if(G.arcs[i][j].info)//有相关信息
{
free(G.arcs[i][j].info);
G.arcs[i][j].info=NULL;
}
}
else//无向
for(i=0;ifor(j=i+1;jif(G.arcs[i][j].adj==1&&G.kind==2||G.arcs[i][j].adj!
=INFINITY&&G.kind==3)//无向图的边||无向网的边
if(G.arcs[i][j].info)//有相关信息
{
free(G.arcs[i][j].info);
G.arcs[i][j].info=G.arcs[j][i].info=NULL;
}
G.vexnum=0;
G.arcnum=0;
}
VertexType&GetVex(MGraphG,intv)
{//初始条件:
图G存在,v是G中某个顶点的序号。
操作结果:
返回v的值
if(v>=G.vexnum||v<0)
exit(ERROR);
returnG.vexs[v];
}
StatusPutVex(MGraph&G,VertexTypev,VertexTypevalue)
{//初始条件:
图G存在,v是G中某个顶点。
操作结果:
对v赋新值value
intk;
k=LocateVex(G,v);//k为顶点v在图G中的序号
if(k<0)
returnERROR;
strcpy(G.vexs[k],value);
returnOK;
}
intFirstAdjVex(MGraphG,VertexTypev)
{//初始条件:
图G存在,v是G中某个顶点
//操作结果:
返回v的第一个邻接顶点的序号。
若顶点在G中没有邻接顶点,则返回-1
inti,j=0,k;
k=LocateVex(G,v);//k为顶点v在图G中的序号
if(G.kind==DN||G.kind==AN)//网
j=INFINITY;
for(i=0;iif(G.arcs[k][i].adj!
=j)
returni;
return-1;
}
intNextAdjVex(MGraphG,VertexTypev,VertexTypew)
{//初始条件:
图G存在,v是G中某个顶点,w是v的邻接顶点
//操作结果:
返回v的(相对于w的)下一个邻接顶点的序号,
//若w是v的最后一个邻接顶点,则返回-1
inti,j=0,k1,k2;
k1=LocateVex(G,v);//k1为顶点v在图G中的序号
k2=LocateVex(G,w);//k2为顶点w在图G中的序号
if(G.kind==DN||G.kind==AN)//网
j=INFINITY;
for(i=k2+1;iif(G.arcs[k1][i].adj!
=j)
returni;
return-1;
}
voidInsertVex(MGraph&G,VertexTypev)
{//初始条件:
图G存在,v和图G中顶点有相同特征
//操作结果:
在图G中增添新顶点v(不增添与顶点相关的弧,留待InsertArc()去做)
inti;
strcpy(G.vexs[G.vexnum],v);//构造新顶点向量
for(i=0;i<=G.vexnum;i