Kruskal算法.pptVIP

  1. 1、本文档共11页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Kruskal算法Kruskal算法

* * Kruskal算法 算法过程: 1.将图各边按照权值进行排序 2.将图遍历一次,找出权值最小的边,(条件:此次找出的边不能和已加入最小生成树集合的边构成环),若符合条件,则加入最小生成树的集合中。不符合条件则继续遍历图,寻找下一个最小权值的边。 3.递归重复步骤1,直到找出n-1条边为止(如果图有n个结点,那么最小生成树的边数应为n-1条),算法结束。得到的就是此图的最小生成树。 typedef struct { char a; char b; int weight; }edgenode; 用结构体存储边的信息,记录边的两个端点和边的权值 edgenode graph[M]; //用graph数组存储图的信息 用快排对输入的边进行排序 qsort(graph, n, sizeof(graph[0]), cmp); //按权值从小到大进行快排 //比较函数,用于快排 int cmp(const void *p, const void *q) { edgenode *a = (edgenode *)p; edgenode *b = (edgenode *)q; return a-weight b-weight ? 1 : -1; } void _union(int a, int b) //合并 { int weight = parent[a] + parent[b]; //weight 放的是两个数节点和的负值 if(parent[a] parent[b]) //节点数多的数的根作为另一棵树的根 { parent[b] = a; parent[a] = weight; } else { parent[a] = b; parent[b] = weight; } } int _find(int x) //压缩路径的find() { int y,z; y = x; while(parent[y] = 0) y = parent[y]; while(x != y) { z = parent[x]; parent[x] = y; x = z; } return y; } int find(int x) { if(parent[x] 0) return x; else return find(parent[x]); } find(x):返回包含x的连通分支的名字。这个函数可以用来确定某条边的两个端点所属的连通分支 int kruskal(int n, int m) //n条边,m个顶点 { int i, total, x, y; for(i=0; im; i++) { parent[i] = -1; //初始化,先使每个节点各自形成一个单元素集合 } for(i=1; in; i++) { x = _find(graph[i].a - A); y = _find(graph[i].b - A); if(x!=y) //若边的两个顶点不属于同一个集合 { _union(x, y); //就合并两个集合 total += graph[i].weight; //加上这条边的权值 } } return total; } 先是按权值递增排序: 对各节点进行初始化(parent[i]=-1),使每个节点都属于单元素集合 根据排序结果,先判断(B,C)是否在同个集合中 find()对于任意给定点x,判断x属于哪一个连通块 如果find(B)==find(C),则两个端点连通,不能合并, 否则就用_union()将B和C合并 *

文档评论(0)

ebitjij + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档