收藏 分享(赏)

图的基本操作与kruskal最小生成树实验报告.doc

上传人:精品资料 文档编号:10737031 上传时间:2020-01-03 格式:DOC 页数:22 大小:217.50KB
下载 相关 举报
图的基本操作与kruskal最小生成树实验报告.doc_第1页
第1页 / 共22页
图的基本操作与kruskal最小生成树实验报告.doc_第2页
第2页 / 共22页
图的基本操作与kruskal最小生成树实验报告.doc_第3页
第3页 / 共22页
图的基本操作与kruskal最小生成树实验报告.doc_第4页
第4页 / 共22页
图的基本操作与kruskal最小生成树实验报告.doc_第5页
第5页 / 共22页
点击查看更多>>
资源描述

1、 1数据结构2实验五 图的基本操作一、实验目的1、使学生可以巩固所学的有关图的基本知识。2、熟练掌握图的存储结构。3、熟练掌握图的两种遍历算法。二、实验内容问题描述对给定图,实现图的深度优先遍历和广度优先遍历。基本要求以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。【测试数据】由学生依据软件工程的测试技术自己确定。三、实验前的准备工作1、掌握图的相关概念。2、掌握图的逻辑结构和存储结构。3、掌握图的两种遍历算法的实现。四、详细设计3建立结构体创建图END调用 greatUDN 函数调用 BFSTraverse 函数输入起始节

2、点名称深度优先遍历输出广度优先遍历输出调用 DFSTraverse 函数五、源程序#define INFINITY 10000 #define MAX_VERTEX_NUM 40#define MAX 40#include#include#include#includetypedef struct ArCellint adj;ArCell,AdjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;typedef structchar name20;infotype;4typedef structinfotype vexsMAX_VERTEX_NUM;AdjMatrix arc

3、s;int vexnum,arcnum;MGraph;int LocateVex(MGraph *G,char* v) int c=-1,i;for(i=0;ivexnum;i+)if(strcmp(v,G-vexsi.name)=0)c=i;break;return c;MGraph * CreatUDN(MGraph *G)/初始化图,接受用户输入int i,j,k,w;char v120,v220;printf(“请输入图的顶点数,弧数:“);scanf(“%d%d“,printf(“结点名字:n“);for(i=0;ivexnum;i+)printf(“No.%d:“,i+1);sca

4、nf(“%s“,G-vexsi.name);for(i=0;ivexnum;i+)for(j=0;jvexnum;j+)G-arcsij.adj=INFINITY;printf(“请输入一条边依附的两个顶点和权值:n“);for(k=0;karcnum;k+)printf(“第%d 条边:n“,k+1);printf(“起始结点:“);scanf(“%s“,v1);printf(“结束结点:“);scanf(“%s“,v2);printf(“边的权值:“);scanf(“%d“,i=LocateVex(G,v1);j=LocateVex(G,v2);if(i=0G-arcsji=G-arcsi

5、j;return G;5int FirstAdjVex(MGraph *G,int v)int i;if(vvexnum) /v 合理for(i=0;ivexnum;i+)if(G-arcsvi.adj!=INFINITY) return i;return -1;void VisitFunc(MGraph *G,int v)printf(“%s “,G-vexsv.name);int NextAdjVex(MGraph *G,int v,int w)int k;if(v=0 kvexnum;k+)if(G-arcsvk.adj!=INFINITY) return k;return -1;int

6、 visitedMAX;void DFS(MGraph *G,int v)/从第 v 个顶点出发递归地深度优先遍历图 Gint w;visitedv=1;VisitFunc(G,v);/访问第 v 个结点for(w=FirstAdjVex(G,v);w=0;w=NextAdjVex(G,v,w)if(!visitedw)DFS(G,w);printf(“%d “,G-arcsvw.adj);void DFSTraverse(MGraph *G,char *s)/深度优先遍历int v,k;for(v=0;vvexnum;v+)visitedv=0;6k=LocateVex(G,s);if(k=

7、0v=0;v-)if(!visitedv)DFS(G,v);for(v=k+1;vvexnum;v+)if(!visitedv)DFS(G,v);typedef struct Qnodeint vexnum;struct Qnode *next;QNode,*QueuePtr;typedef structQueuePtr front;QueuePtr rear;LinkQueue;int InitQueue(LinkQueue *Q)Q-front=Q-rear=(QueuePtr)malloc(sizeof(QNode);if(!Q-front)exit(0);Q-front-next=NU

8、LL;return 1;void EnQueue(LinkQueue *Q,int a ) QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode);if(!p)exit(0);p-vexnum=a;p-next=NULL;Q-rear-next=p;Q-rear=p;int DeQueue(LinkQueue *Q,int *v) QueuePtr p;if(Q-front=Q-rear)7printf(“结点不存在!n“);exit(0);p=Q-front-next;*v=p-vexnum;Q-front-next=p-next;if(Q-rear=p)Q-

9、front=Q-rear;return *v;int QueueEmpty(LinkQueue *Q)if(Q-rear=Q-front)return 0;return 1;int VisitedMAX;void BFSTraverse(MGraph *G,char *str)/广度优先遍历int w,u,v,k;LinkQueue Q,q;for(v=0;vvexnum;v+) Visitedv=0;InitQueue(InitQueue(k=LocateVex(G,str);for(v=k;v=0;v-)if(!Visitedv)Visitedv=1;VisitFunc(G,v);EnQu

10、eue(/v 入队while(!QueueEmpty(/出队for(w=FirstAdjVex(G,u);w=0;w=NextAdjVex(G,u,w)if(!Visitedw)Visitedw=1;VisitFunc(G,v);EnQueue(for(v=k+1;vvexnum;v+)if(!Visitedv)8Visitedv=1;VisitFunc(G,v);EnQueue(/v 入队while(!QueueEmpty(/出队for(w=FirstAdjVex(G,u);w=0;w=NextAdjVex(G,u,w)if(!Visitedw)Visitedw=1;VisitFunc(G,

11、v);EnQueue(void main()MGraph *G,b;char v10;G=CreatUDN(printf(“请输入起始结点名称:“);scanf(“%s“,v);printf(“n 深度优先遍历:n“);DFSTraverse(G,v);printf(“n 广度优先遍历:n“);BFSTraverse(G,v);getch();六、测试数据及调试910实验六 图的应用一、实验目的1、使学生可以巩固所学的有关图的基本知识。2、熟练掌握图的存储结构。3、掌握如何应用图解决各种实际问题。二、实验内容本次实验提供 2个题目,学生可以任选一个!题目一:最小生成树问题问题描述若要在 n 个

12、城市之间建设通信网络,只需要假设 n-1 条线路即可。如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题。基本要求1利用克鲁斯卡尔算法求网的最小生成树。2要求输出各条边及它们的权值。实现提示通信线路一旦建成,必然是双向的。因此,构造最小生成树的网一定是无向网。设图的顶点数不超过 30 个,并为简单起见,网中边的权值设成小于 100的整数。图的存储结构的选取应和所作操作相适应。为了便于选择权值最小的边,此题的存储结构既不选用邻接矩阵的数组表示法,也不选用邻接表,而是以存储边(带权)的数组表示图三、详细设计。存储结构该函数包含三个结构体,即存储顶点、存储边和存储图的结构体,其结构体分别如

13、下所示:1.顶点和边的存储表示用字符串 name 表示顶点信息,num 表示顶点的序号。struct nodechar name10;int num;vex20;11用整型 begin 和 end 表示边的起点和终点,weight 表示边的权值。typedef struct int begin;int end;int weight;edge;2.图的邻接矩阵存储表示用整型 adj 表示顶点间的关系,weight 表示权值。typedef structint adj;int weight;AdjMatrixMAXMAX;用 arc 表示邻接矩阵, vexnum 和 arcnum 表示图当前的顶点

14、数和边数。typedef structAdjMatrix arc;int vexnum, arcnum;MGraph; 3.2 算法描述该算法是建立一个带权的无向图,并用 Kruskal 算法求该图的最小生成树,用父结点和子女结点集的形式输出最小生成树。1 无向带权图的建立图的存储结构如上所示,;用 adj 是否为 1 判断两顶点间是否有边, adj为 1 时表示有边,反之没有边,vexnum 和 arcnum 分别表示顶点数和边数,name 和 num 分别表示顶点信息和顶点序号,建图的算法如下所示:void CreatGraph(MGraph *G)int i, j,n,h,m,k;cha

15、r uMAX,vMAX;printf(“请输入边数和顶点数:“);scanf(“%d %d“, i vexnum; i+)/初始化图12for ( j = 1; j vexnum; j+)G-arcij.adj = G-arcji.adj = 0;printf(“n 请输入顶点的信息:“);for(n=1;nvexnum;n+) scanf(“%s“,vexn.name);vexn.num=n;for ( i = 1; i arcnum; i+) printf(“n 请输入有边的 2 个顶点:“);scanf(“%s“,v);scanf(“%s“,u);for ( k= 1; k vexnum

16、; k+) if(strcmp(v,vexk.name)=0)m=vexk.num;if(strcmp(u,vexk.name)=0)h=vexk.num;G-arcmh.adj = G-archm.adj = 1;getchar();printf(“n 请输入%s 与%s 之间的权值:“,vexm.name, vexh.name);scanf(“%d“,13printf(“邻接矩阵为:n“);for ( i = 1; i vexnum; i+) for ( j = 1; j vexnum; j+)printf(“%d “,G-arcij.adj);printf(“n“);2. Kruskal

17、 算法克鲁斯卡尔算法:假设连通网 N=(V,E) ,则令最小生成树的起始状态为只有 n个顶点而无边的非连通图 T=(V,) ,图中每个顶点自成一个连通分量。在 E中选择代价最小的边,若该边依附的顶点落在 T中不同的连通分量上,则将此边加到 T中,否则舍去此边而选择下一条代价最小的边。以此类推,直至 T中所有的顶点都在同一连通分量上为止。算法代码如下所示:void MiniSpanTree(MGraph *G) int i, j, n, m;int k = 1;int parentM;edge edgesM;for ( i = 1; i vexnum; i+)for (j = i + 1; j

18、vexnum; j+)if (G-arcij.adj = 1)edgesk.begin = i;14edgesk.end = j;edgesk.weight = G-arcij.weight;k+;sort(edges, G);for (i = 1; i arcnum; i+)parenti = 0;printf(“最小生成树为:n“);for (i = 1; i arcnum; i+) n = Find(parent, edgesi.begin);m = Find(parent, edgesi.end);if (n != m)parentn = m;printf(“ %dn“, vexedg

19、esi.begin.name, vexedgesi.end.name, edgesi.weight);int Find(int *parent, int f)while ( parentf 0)15f = parentf;return f;3用起泡法对边权值按从小到大的顺序排列 void sort(edge edges ,MGraph *G) int i, j;int temp;for ( i = 1; i arcnum; i+)for ( j = i+1; j arcnum; j+)if (edgesi.weight edgesj.weight)temp = edgesi.begin; ed

20、gesi.begin = edgesj.begin;edgesj.begin = temp;temp = edgesi.end; edgesi.end = edgesj.end;edgesj.end = temp;temp = edgesi.weight; edgesi.weight = edgesj.weight;edgesj.weight = temp;四、调试4.1 调试过程经过我仔细的调试发现以下三个问题1、问题一:求出图中的最小值 现象:求出的最小值是0原因:图中没有连通的两个顶点之间的权值赋值为02、问题二:求最小生成树时,出现漏洞现象:对某些二叉树能求出最小生成树,但不能普遍适应

21、原因:对于找最小生成树边的各种可能没有考虑全面,代码才没有广泛的16适应性3、问题三:两个顶点之间的边是否是最小生成树的边现象:代码的功能不能分辨出是否是最小生成树的边原因:把简单的代码写的很复杂,从而杂乱无章出现错误。4.2程序执行过程1.图 4.2.1 所示为一 10 条边 6 个顶点的无向带权图的顶点间的关系,图4.2.2 为输入顶点及边权值的运行情况,图 4.2.3 为邻接矩阵和最小生成树的输出结果。17运行结果:18五、源代码#include#include#include#include#define M 20#define MAX 20struct nodechar name10

22、;int num;vex20;typedef struct int begin;int end;int weight;edge;typedef struct19int adj;int weight;AdjMatrixMAXMAX;typedef structAdjMatrix arc;int vexnum, arcnum;MGraph; void CreatGraph(MGraph *);void MiniSpanTree(MGraph *);void sort(edge* ,MGraph *);int Find(int *, int );void CreatGraph(MGraph *G)i

23、nt i, j,n,h,m,k;char uMAX,vMAX;printf(“请输入边数和顶点数:“);scanf(“%d %d“,for (i = 1; i vexnum; i+)/初始化图for ( j = 1; j vexnum; j+)G-arcij.adj = G-arcji.adj = 0;printf(“n 请输入顶点的信息:“);for(n=1;nvexnum;n+) scanf(“%s“,vexn.name);vexn.num=n;for ( i = 1; i arcnum; i+) printf(“n 请输入有边的 2 个顶点:“);scanf(“%s“,v);scanf(

24、“%s“,u);for ( k= 1; k vexnum; k+) if(strcmp(v,vexk.name)=0)m=vexk.num;20if(strcmp(u,vexk.name)=0)h=vexk.num;G-arcmh.adj = G-archm.adj = 1;getchar();printf(“n 请输入%s 与%s 之间的权值:“,vexm.name, vexh.name);scanf(“%d“,printf(“邻接矩阵为:n“);for ( i = 1; i vexnum; i+) for ( j = 1; j vexnum; j+)printf(“%d “,G-arcij

25、.adj);printf(“n“);void sort(edge edges ,MGraph *G)/对权值进行排序 int i, j;int temp;for ( i = 1; i arcnum; i+)for ( j = i+1; j arcnum; j+)if (edgesi.weight edgesj.weight)temp = edgesi.begin; edgesi.begin = edgesj.begin;edgesj.begin = temp;temp = edgesi.end; edgesi.end = edgesj.end;edgesj.end = temp;temp =

26、edgesi.weight; edgesi.weight = edgesj.weight;edgesj.weight = temp;printf(“权排序之后的为:n“);21for (i = 1; i arcnum; i+)printf(“ %dn“, vexedgesi.begin.name, vexedgesi.end.name, edgesi.weight);void MiniSpanTree(MGraph *G) int i, j, n, m;int k = 1;int parentM;edge edgesM;for ( i = 1; i vexnum; i+)for (j = i

27、+ 1; j vexnum; j+)if (G-arcij.adj = 1)edgesk.begin = i;edgesk.end = j;edgesk.weight = G-arcij.weight;k+;sort(edges, G);for (i = 1; i arcnum; i+)parenti = 0;printf(“最小生成树为:n“);for (i = 1; i arcnum; i+) n = Find(parent, edgesi.begin);m = Find(parent, edgesi.end);if (n != m)parentn = m;printf(“ %dn“, vexedgesi.begin.name, vexedgesi.end.name, edgesi.weight);22int Find(int *parent, int f)while ( parentf 0)f = parentf;return f;void main() MGraph *G;char p;G = (MGraph*)malloc(sizeof(MGraph);CreatGraph(G);MiniSpanTree(G);scanf(“%s“,if(p=out)exit(0);

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报