图的实验报告.docx
- 文档编号:9457706
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:23
- 大小:19.11KB
图的实验报告.docx
《图的实验报告.docx》由会员分享,可在线阅读,更多相关《图的实验报告.docx(23页珍藏版)》请在冰豆网上搜索。
图的实验报告
《数据结构》
实验报告
题目:
图
一、实现图的邻接矩阵和邻接表存储
(一)需求分析
对于下图所示的有向图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、主程序的流程以及各程序模块之间的层次调用关系,函数的调用关系图:
Main()
DispMat(g);输出邻
MatToList(g,G);将邻接矩
DispAdj(G);输出
接矩阵g
阵g转换成邻接表G
邻接表G
3、列出各个功能模块的主要功能及输入输出参数
voidMatToList(MGraphg,ALGraph*&G)将邻接矩阵
voidDispMat(MGraphg)输出邻接矩阵g
voidDispAdj(ALGraph*G)输出邻接表G
intOutDegree(ALGraph*G,intv)求图中每个顶点的出度
g转换成邻接表
G
(三)调试分析
调试过程中还是出现了一些拼写错误,
经检查后都能及时修正。
有些是语法设计上的小
错误,比如一些参变量的初始值设置错误,
使得程序调试出错。
在小组讨论分析后纠正了这
些结果,并尽量改进了算法的性能,减小时间复杂度。
将邻接矩阵
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和边数
}ALGraph;//图的邻接表类型
voidMatToList(MGraphg,ALGraph*&G)//将邻接矩阵
{
e
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.主程序的流程以及各程序模块之间的层次调用关系,画出函数的调用关系图。 Main() CreatMGraph(G) DFS(G);深度 BFS(G,0);以序号 为3的顶点开始广 建立邻接矩阵 优先遍历 度优先遍历 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]) DFSM(G,i); //Vi 未访问过 //以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]); visited[k]=TRUE; cq[r]=k;//Vk //定义队列 //标志向量初始化 //队列初始化 //访问源点Vk 已访问,将其入队。 注意,实际上是将其序号入队 while(cq[f]! =-1){//队非空则执行 i=cq[f];f=f+1;//Vf出队 for(j=0;j if(G->edges[i][j]==1&&! visited[j]){ printf("%c",G->vexs[j]); visited[j]=TRUE; r=r+1;cq[r]=j;//访问过 的邻接点Vj //Vj未访问 //访问Vj 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文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 报告