图的最小生成树的实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程设计
设计说明书
图的最小生成树的实现(Kruskal算法)
(Kruskal算法)
计算机科学与技术系
2011 年 3 月 4 日
数据结构课程设计评阅书
指导教师(签字):教研室主任(签字):批准日期:年月日
图的最小生成树的实现(Kruskal算法)是一种按照网中边的权值递增的顺序构造最小生成树的方法.在构造过程中,按照网中边的权值由小到大的顺序,不断选取当前当前为被选取的边集中权值最小的边.最后形成的连通分量便是最小生成树.在存储图时选取邻接矩表.此算法的关键问题是如何判断回路,解决办法是定义一个一维数组,让f[i]=I,在增加边时判断f[i]是否和f[j]相同.这样的设计更方便实用,可以使用户更好的使用.
关键词:邻接矩阵;邻接表;kruskal;最小生成树
1 课题描述 (1)
2问题分析和任务定义 (2)
3 逻辑设计 (3)
4 程序编码 (5)
6 总结 (10)
参考文献 (11)
1 课题描述
图的最小生成树的定义:设图连通G的所有边的集合E(G),在从任意顶点出发便利图时,必定将E(G)分为两部分,一个是便利的边的集合,另一个是剩余的.把经历的边的集合和图G中所有顶点一起构成连通图G的极小连通子图。这个连通图是一棵生成树,无向连通图的生成树不是唯一的,连通图的一次遍历所经历的边的集合及图中所有顶点的集合就构成了该图的一棵生成树,对连通图的不同遍历,就可得到不同的生成树。如果无相连通图是一个网,那么它所有生成树中必有一棵边的权值总和最小的生成树,我们称这棵树是最小生成树。本次课设将采用Kruskal算法解决最小生成树问题。
1
2问题分析和任务定义
本次课设任务是设计图的最小生成树的kruskal算法。
先简单介绍此算法:
假设T中的边和顶点均涂成红色,其余边为白色。开始时G中的边均为白色。
1)将所有顶点涂成红色;
2)在白色边中,挑选一条权最小的边,使其与红色边不形成圈,将该白色边涂红;
3)重复2)直到有n-1条红色边,这n-1条红色边便构成最小生成树T的边集合。
注意到在算法执行过程中,红色顶点和红色边会形成一个或多个连通分支,它们都是G的子树。一条边与红色边形成圈当且仅当这条边的两个端点属于同一个子树。因此判定一条边是否与红色边形成圈,只需判断这条边的两端点是否属于同一个子树。
上述判断可以如此实现:给每个子树一个不同的编号,对每一个顶点引入一个标记t,表示这个顶点所在的子树编号。当加入一条红色边,就会使该边两端点所在的两个子树连接起来,成为一个子树,从而两个子树中的顶点标记要改变成一样。综上,可将Kruskal算法细化使其更容易计算机实现。
在实际的操作中:
1)采用邻接矩阵录入图并转化成邻接表形式。
2)系统扫描邻接表遍历图。
3)根据权值找到最小边生成最小树。
4)生成最小树时要考虑到如何判断是否回路的问题。
3 逻辑设计
图 3.1 kruskal流程图
4 程序编码
/*利用Kruskal算法求图的最小生成树*/
#include
#include
#define MaxVertexNum 12
#define MaxEdgeNum 20
#define MaxValue 1000
typedef int VertexType;
typedef VertexType vexlist[MaxVertexNum];
typedef int adjmatrix[MaxVertexNum][MaxVertexNum]; int visited[MaxVertexNum]={0};
struct edgeElem
{
int fromvex; /*边的起点域*/
int endvex; /*边的终点域*/
int weight; /*边的权值域*/
};
typedef struct edgeElem edgeset[MaxEdgeNum];
void Kruskal(edgeset GE ,edgeset C,int n)
{
int i,j,k,d,m1,m2;
adjmatrix s;
for(i=0;i { for(j=0;j if(i==j) s[i][j]=1; else s[i][j]=0; } k=1; d=0; while(k { for(i=0;i { if(s[i][GE[d].fromvex]==1) m1=i; if(s[i][GE[d].endvex]==1) m2=i; } if(m1!=m2) { C[k-1]=GE[d]; k++; for(j=0;j { s[m1][j]=s[m1][j]||s[m2][j]; s[m2][j]=0; } } d++; } } void Create(vexlist GV,edgeset GE,int n,int e) /*建立顶点数组GV和边集数组GE*/ { int i,j,k,w; printf("输入%d个顶点数据\n",n); for(i=0;i printf("输入%d条带权边\n",e); for(k=0;k { scanf("%d %d %d",&i,&j,&w); GE[k].fromvex=i; GE[k].endvex=j; GE[k].weight=w; } } void outputEdgeset(edgeset GE,int e) /*输出一个图的邻接矩阵*/ { int i; for(i=0;i printf("%d %d %d, ",GE[i].fromvex, GE[i].endvex,GE[i].weight); printf("\n"); }