Kruskal 的 C 算法及其作用
Kruskal's Algorithm In C And What It Does
我有我的教授给我的关于使用 Kruskal 算法查找 MST 的代码。但是,我不明白
到底需要什么
int parent[10]
是以及当我们使用函数时发生了什么
find()
和
uni()
下面是他给我们的完整代码。
#include <stdio.h>
int parent[10];
int find(int i)
{
while(parent[i])
{
i=parent[i];
}
return i;
}
int uni(int i,int j)
{
if(i!=j)
{
parent[j]=i;
return 1;
}
return 0;
}
int main(void)
{
int cost[10][10],u,v,i,j,min,mincost=0,n,ne=1,a,b;
printf("Enter no. of vertices: ");
scanf("%d",&n);
printf("Enter Adjacency Matrix:\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&cost[i][j]);
}
}
while(ne<n)
{
min=999;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(cost[i][j]<min)
{
min=cost[i][j];
a=u=i;
b=v=j;
}
}
}
u=find(u);
v=find(v);
if(uni(u,v))
{
printf("\n%d edge(%d -> %d)=%d",ne++,a,b,min);
mincost += min;
}
cost[a][b]=cost[b][a]=999;
}
printf("\nMin. cost of spanning tree=%d",mincost);
return 0;
}
我只是在寻找对我上面所说的三件事的解释。除了我陈述的三件事外,我了解该算法的工作原理。
谢谢
此代码最多支持 10 个顶点。
parent
正在跟踪节点的父节点。
find
用于查找没有任何父节点的集合(比如 A)中的顶点。
因此,如果 u 在集合 A 中而 v 在集合 B 中,则这两个集合将通过 uni
函数合并。
此代码有效,但不是您的编码方式。
关于算法本身:
Kruskal 是一种贪心算法,用于寻找具有最少(或最大)成本的最小生成树。算法如下:
- 按升序或降序对所有权重进行排序。
- 找到具有最小(或最大)成本的边。
- 如果边是
uv
检查u
和v
是否属于同一个集合。如果是,则从步骤 2 开始什么都不做。
- 如果没有联合存在
u
和 v
的集合,即如果 u 在集合 A 中,v 在集合 B 中,将 A 和 B 联合为 C 并丢弃 A 和 B。现在u
和 v
属于 C。从步骤 2 开始重复。
这是一个更好的代码:
https://github.com/26prajval98/DSA/blob/master/graph%20algorithms/kruskal/main.c
我有我的教授给我的关于使用 Kruskal 算法查找 MST 的代码。但是,我不明白
到底需要什么int parent[10]
是以及当我们使用函数时发生了什么
find()
和
uni()
下面是他给我们的完整代码。
#include <stdio.h>
int parent[10];
int find(int i)
{
while(parent[i])
{
i=parent[i];
}
return i;
}
int uni(int i,int j)
{
if(i!=j)
{
parent[j]=i;
return 1;
}
return 0;
}
int main(void)
{
int cost[10][10],u,v,i,j,min,mincost=0,n,ne=1,a,b;
printf("Enter no. of vertices: ");
scanf("%d",&n);
printf("Enter Adjacency Matrix:\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&cost[i][j]);
}
}
while(ne<n)
{
min=999;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(cost[i][j]<min)
{
min=cost[i][j];
a=u=i;
b=v=j;
}
}
}
u=find(u);
v=find(v);
if(uni(u,v))
{
printf("\n%d edge(%d -> %d)=%d",ne++,a,b,min);
mincost += min;
}
cost[a][b]=cost[b][a]=999;
}
printf("\nMin. cost of spanning tree=%d",mincost);
return 0;
}
我只是在寻找对我上面所说的三件事的解释。除了我陈述的三件事外,我了解该算法的工作原理。
谢谢
此代码最多支持 10 个顶点。
parent
正在跟踪节点的父节点。find
用于查找没有任何父节点的集合(比如 A)中的顶点。 因此,如果 u 在集合 A 中而 v 在集合 B 中,则这两个集合将通过uni
函数合并。
此代码有效,但不是您的编码方式。
关于算法本身:
Kruskal 是一种贪心算法,用于寻找具有最少(或最大)成本的最小生成树。算法如下:
- 按升序或降序对所有权重进行排序。
- 找到具有最小(或最大)成本的边。
- 如果边是
uv
检查u
和v
是否属于同一个集合。如果是,则从步骤 2 开始什么都不做。 - 如果没有联合存在
u
和v
的集合,即如果 u 在集合 A 中,v 在集合 B 中,将 A 和 B 联合为 C 并丢弃 A 和 B。现在u
和v
属于 C。从步骤 2 开始重复。
这是一个更好的代码: https://github.com/26prajval98/DSA/blob/master/graph%20algorithms/kruskal/main.c