克鲁斯卡尔算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了克鲁斯卡尔算法相关的知识,希望对你有一定的参考价值。
你好!这是代码
/* Kruskal算法生成最小生成树 */
void MiniSpanTree_Kruskal (MGraph G) /* 生成最小生成树 */
int i, n, m;
Edge edges[MAXEDGE]; /* 定义边集数组 */
int parent[MAXVEX]; /* 定义一数组用来判断边与边是否形成环路 */
/* 此处省略将邻接矩阵G转化为边集数组edges,并按权由小到大排列的代码 */
for (i=0; i<G.numVertexes; i++)
parent[i] = 0; /* 初始化数组为0 */
for(i=0; i<G.numEdges; i++) /* 循环每一条边 */
n = Find(parent, edges[i].begin);
m = Find(parent, edges[i].end);
if (n != m) /* 假如n与m不等,说明此边没有与现有生成树形成环路 */
parent[n] = m; /* 将此边的结尾顶点放入下标为起点的parent中,表示此顶点已经在生成树集合中 */
printf("(%d,%d) %d ",edges[i].begin,edges[i].end,edges[i].weight);
int Find(int* parent, int f) /* 查找连线顶点的尾部下标 */
while(parent[f] > 0)
f = parent[f];
return f;
请问这个parent数组的作用是什么,为什么要赋初值0;
还有就是:
f (n != m) /* 假如n与m不等,说明此边没有与现有生成树形成环路 */
parent[n] = m; /* 将此边的结尾顶点放入下标为起点的parent中,表示此顶点已经在生成树集合中 */
int Find(int* parent, int f) /* 查找连线顶点的尾部下标 */
while(parent[f] > 0)
f = parent[f];
return f;
这两部分实在是不懂,求大神指教!
这个结构就是一个树的双亲表示,当新边的两个顶点所在的树根不是同一个时,自然就是表示加入这两个顶点间的边不够成环路
这种结构通称“并查集”,用来检测等价关系的,这里用来判断顶点是否在一个集合中,可以看比较全面的《数据结构》教材树那个一章的介绍追问
树的章节会讲并查集吗?能否详细讲解下int Find(int* parent, int f) 的构思
追答并查集的存储结构本来就是一个树的双亲表示,一般比较全的教材都在树那一章里面
你的程序中根的双亲用0表示,find函数中的那个循环就是找到这个树根的编号(下标)
parent数组装的是每个连通分量的第一个开始点,最初的状态有n个节点,n个分量,都是第一个,所以全都赋值0,而开始合并后,将一个个的分量逐步的合并到一起,parent记录的就是父节点,一个联通分量只有一个parent为0的。
而判断循环是如果两个的最终的开始节点是同一个,就说明你加上这条边就形成循环了,这条边就不能加
以上是关于克鲁斯卡尔算法的主要内容,如果未能解决你的问题,请参考以下文章