图的实验报告.docx
- 文档编号:4305866
- 上传时间:2022-11-29
- 格式:DOCX
- 页数:13
- 大小:94.86KB
图的实验报告.docx
《图的实验报告.docx》由会员分享,可在线阅读,更多相关《图的实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
图的实验报告
《数据结构》
实验报告
题目:
图
一、实现图的邻接矩阵和邻接表存储
(一)需求分析
对于下图所示的有向图G,编写一个程序完成如下功能:
1.建立G的邻接矩阵并输出之
2.由G的邻接矩阵产生邻接表并输出之
3.再由2的邻接表产生对应的邻接矩阵并输出之
(二)系统设计
1、本程序中用到的所有抽象数据类型的定义;
typedefstruct
{intno;
InfoTypeinfo;
}VertexType;//顶点类型
typedefstruct//图的定义
{intedges[MAXV][MAXV];
intvexnum,arcnum;
VertexTypevexs[MAXV];
}MGraph;//图的邻接矩阵类型
typedefstructANode//弧的结点结构类型
{intadjvex;
structANode*nextarc;
InfoTypeinfo;
}ArcNode;
typedefintVertex;
typedefstructVnode//邻接表头结点的类型
{Vertexdata;
ArcNode*firstarc;//指向第一条弧
}VNode;
typedefVNodeAdjList[MAXV];//AdjList是邻接表类型
typedefstruct
{AdjListadjlist;//邻接表
intn,e;
}ALGraph;//图的邻接表类型
2、主程序的流程以及各程序模块之间的层次调用关系,函数的调用关系图:
3、列出各个功能模块的主要功能及输入输出参数
voidMatToList(MGraphg,ALGraph*&G)将邻接矩阵g转换成邻接表G
voidDispMat(MGraphg)输出邻接矩阵g
voidDispAdj(ALGraph*G)输出邻接表G
intOutDegree(ALGraph*G,intv)求图中每个顶点的出度
(三)调试分析
调试过程中还是出现了一些拼写错误,经检查后都能及时修正。
有些是语法设计上的小错误,比如一些参变量的初始值设置错误,使得程序调试出错。
在小组讨论分析后纠正了这些结果,并尽量改进了算法的性能,减小时间复杂度。
将邻接矩阵g转换成邻接表G,输出邻接矩阵g,输出邻接表G的算法时间复杂度都是O(n^2)。
通过这次实验,对图的存储方法有了更深刻的印象。
(四)测试结果
测试结果:
(1)有向图G的邻接矩阵为
0104
0092
3580
0060
(2)图G的邻接矩阵转换成的邻接表为:
0:
13
1:
23
2:
012
3:
2
(五)用户手册
不需要输入参数
(六)附录
源程序
#include
#include
#defineMAXV100//最大顶点个数
#defineINF32767//INF表示∞
typedefintInfoType;
typedefstruct
{
intno;//顶点编号
InfoTypeinfo;//顶点其他信息
}VertexType;//顶点类型
typedefstruct//图的定义
{
intedges[MAXV][MAXV];//邻接矩阵
intvexnum,arcnum;//顶点数,弧数
VertexTypevexs[MAXV];//存放顶点信息
}MGraph;//图的邻接矩阵类型
typedefstructANode//弧的结点结构类型
{
intadjvex;//该弧的终点位置
structANode*nextarc;//指向下一条弧的指针
InfoTypeinfo;//该弧的相关信息,这里用于存放权值
}ArcNode;
typedefintVertex;
typedefstructVnode//邻接表头结点的类型
{
Vertexdata;//顶点信息
ArcNode*firstarc;//指向第一条弧
}VNode;
typedefVNodeAdjList[MAXV];//AdjList是邻接表类型
typedefstruct
{
AdjListadjlist;//邻接表
intn,e;//图中顶点数n和边数e
}ALGraph;//图的邻接表类型
voidMatToList(MGraphg,ALGraph*&G)//将邻接矩阵g转换成邻接表G
{
inti,j,n=g.vexnum;//n为顶点数
ArcNode*p;
G=(ALGraph*)malloc(sizeof(ALGraph));
for(i=0;i G->adjlist[i].firstarc=NULL; for(i=0;i for(j=n-1;j>=0;j--) if(g.edges[i][j]! =0)//邻接矩阵的当前元素不为0 { p=(ArcNode*)malloc(sizeof(ArcNode));//创建一个结点*p p->adjvex=j; p->info=g.edges[i][j]; p->nextarc=G->adjlist[i].firstarc;//将*p链到链表后 G->adjlist[i].firstarc=p; } G->n=n;G->e=g.arcnum; } voidDispMat(MGraphg) //输出邻接矩阵g { inti,j; for(i=0;i { for(j=0;j if(g.edges[i][j]==INF) printf("%3s","∞"); else printf("%3d",g.edges[i][j]); printf("\n"); } } voidDispAdj(ALGraph*G) //输出邻接表G { inti; ArcNode*p; for(i=0;i { p=G->adjlist[i].firstarc; if(p! =NULL)printf("%3d: ",i); while(p! =NULL) { printf("%3d",p->adjvex); p=p->nextarc; } printf("\n"); } } intOutDegree(ALGraph*G,intv)//求图中每个顶点的出度 { ArcNode*p; intn=0; p=G->adjlist[v].firstarc; while(p! =NULL) {n++; p=p->nextarc; } returnn; } voidmain() { inti,j; MGraphg,g1; ALGraph*G; intA[MAXV][4]={ {0,1,0,4}, {0,0,9,2}, {3,5,8,0}, {0,0,6,0},}; g.vexnum=4;g.arcnum=8; for(i=0;i for(j=0;j g.edges[i][j]=A[i][j]; printf("\n"); printf(" (1)有向图G的邻接矩阵为: \n"); DispMat(g); G=(ALGraph*)malloc(sizeof(ALGraph)); printf(" (2)图G的邻接矩阵转换成邻接表为: \n"); MatToList(g,G); DispAdj(G); } 运行后结果显示: 二、实现图的遍历算法 (一)需求分析 对于上图G,编写一个程序输出从顶点0开始的深度优先遍历序列(递归算法)和广度优先遍历序列(非递归算法)。 (二)系统设计 1.说明本程序中用到的所有抽象数据类型的定义; typedefstruct{ charvexs[MaxVertexNum];//顶点表 intedges[MaxVertexNum][MaxVertexNum];//邻接矩阵,可看作边表 intn,e;//图中的顶点数n和边数e }MGraph;//用邻接矩阵表示的图的类型 2. 主程序的流程以及各程序模块之间的层次调用关系,画出函数的调用关系图。 3.列出各个功能模块的主要功能及输入输出参数。 voidCreatMGraph(MGraph*G)创建邻接矩阵G voidDFSM(MGraph*G,inti)以Vi为出发点对0-1邻接矩阵表示的图G进行DFS搜索 voidDFS(MGraph*G)深度优先遍历 voidBFS(MGraph*G,intk)以Vk为源点对用邻接矩阵表示的图G进行广度优先遍历 (三)调试分析 调试过程中还是出现了一些拼写错误,经检查后都能及时修正。 有些是语法设计上的小错误,比如一些参变量的初始值设置错误,使得程序调试出错。 在小组讨论分析后纠正了这些结果,并尽量改进了算法的性能,减小时间复杂度。 创建邻接矩阵算法的时间复杂度是O(2n+n^2),深度优先遍历和广度优先遍历的算法时间复杂度都是O(n^2)。 通过这次实验,加深了对遍历图的递归和非递归的算法的印象。 (四)测试结果 输入节点数8和边数9,各节点标示01234567,边是01,02,13,14,25,26,37,47,56,运行后深度优先遍历是01374256,广度优先遍历是01234567。 (五)用户手册 根据提示输入节点和边数,然后再由提示输入各节点标示,接下来输入各边。 运行后便得到深度优先遍历和广度优先遍历结果。 (六)附录 源程序: #include"stdio.h" #include"stdlib.h" #defineMaxVertexNum100//定义最大顶点数 typedefstruct{ charvexs[MaxVertexNum];//顶点表 intedges[MaxVertexNum][MaxVertexNum];//邻接矩阵,可看作边表 intn,e;//图中的顶点数n和边数e }MGraph;//用邻接矩阵表示的图的类型 voidCreatMGraph(MGraph*G)//建立邻接矩阵 { inti,j,k; chara; printf("InputVertexNum(n)andEdgesNum(e): "); scanf("%d,%d",&G->n,&G->e);//输入顶点数和边数 scanf("%c",&a); printf("InputVertexstring: "); for(i=0;i { scanf("%c",&a); G->vexs[i]=a;//读入顶点信息,建立顶点表 } for(i=0;i for(j=0;j G->edges[i][j]=0;//初始化邻接矩阵 printf("Inputedges,CreatAdjacencyMatrix\n"); for(k=0;k scanf("%d%d",&i,&j);//输入边(Vi,Vj)的顶点序号 G->edges[i][j]=1; G->edges[j][i]=1;//若为无向图,矩阵为对称矩阵;若建立有向图,去掉该条语句 } } typedefenum{FALSE,TRUE}Boolean; Booleanvisited[MaxVertexNum]; voidDFSM(MGraph*G,inti) {//以Vi为出发点对邻接矩阵表示的图G进行DFS搜索,邻接矩阵是0,1矩阵 intj; printf("%c",G->vexs[i]);//访问顶点Vi visited[i]=TRUE;//置已访问标志 for(j=0;j if(G->edges[i][j]==1&&! visited[j]) DFSM(G,j);//(Vi,Vj)∈E,且Vj未访问过,故Vj为新出发点 } voidDFS(MGraph*G) { inti; for(i=0;i visited[i]=FALSE;//标志向量初始化 for(i=0;i if(! visited[i])//Vi未访问过 DFSM(G,i);//以Vi为源点开始DFS搜索 } voidBFS(MGraph*G,intk) {//以Vk为源点对用邻接矩阵表示的图G进行广度优先搜索 inti,j,f=0,r=0; intcq[MaxVertexNum];//定义队列 for(i=0;i visited[i]=FALSE;//标志向量初始化 for(i=0;i cq[i]=-1;//队列初始化 printf("%c",G->vexs[k]);//访问源点Vk visited[k]=TRUE; cq[r]=k;//Vk已访问,将其入队。 注意,实际上是将其序号入队 while(cq[f]! =-1){//队非空则执行 i=cq[f];f=f+1;//Vf出队 for(j=0;j if(G->edges[i][j]==1&&! visited[j]){//Vj未访问 printf("%c",G->vexs[j]);//访问Vj visited[j]=TRUE; r=r+1;cq[r]=j;//访问过Vj入队 } } } voidmain() { inti; MGraph*G; G=(MGraph*)malloc(sizeof(MGraph));//为图G申请内存空间 CreatMGraph(G);//建立邻接矩阵 printf("PrintGraphDFS: "); DFS(G);//深度优先遍历 printf("\n"); printf("PrintGraphBFS: "); BFS(G,0);//以序号为3的顶点开始广度优先遍历 printf("\n"); } 测试结果
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)