【问题标题】:Kruskal's Algorithm In C And What It DoesC语言中的克鲁斯卡尔算法及其作用
【发布时间】:2019-06-03 03:02:26
【问题描述】:

我有我的教授给我的关于使用 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;
}

我只是在寻找对我上面所说的三件事的解释。除了我所说的三件事之外,我了解算法的工作原理。

谢谢

【问题讨论】:

  • 关于:scanf("%d",&amp;n); printf("Enter Adjacency Matrix:\n"); for(i=1;i&lt;=n;i++) { for(j=1;j&lt;=n;j++) { scanf("%d",&amp;cost[i][j]); } } 如果n 大于 9,则由于访问超出矩阵的末尾cost[][] 可悲的是,没有检查这种无效值(就像没有检查来自scanf() 的返回值以确保操作成功
  • 在 C 中,数组索引从 0 开始,而不是 1,因此cost[][] 数组的第一行和每行的第一列永远不会被设置为任何已知值
  • 关于:for(j=1;j&lt;=n;j++) { scanf("%d",&amp;cost[i][j]); } 如果扫描的值 >9 或小于 0 那么结果(在函数中:find())是未定义的行为。
  • 关于:cost[a][b]=cost[b][a]=999;find() 函数中,由于访问超出cost[][] 数组的末尾,这将导致未定义的行为

标签: c kruskals-algorithm


【解决方案1】:

此代码最多支持 10 个顶点。

  • parent 正在跟踪节点的父节点。
  • find 用于在没有任何父节点的集合(比如 A)中查找顶点。 因此,如果 u 在集合 A 中,v 在集合 B 中,则这两个集合通过 uni 函数合并。

此代码有效,但不是您的编码方式。

关于算法本身:

Kruskal 是一种贪心算法,用于找到具有最小(或最大成本)的最小生成树。算法如下:

  • 按升序或降序对所有权重进行排序。
  • 找到成本最低(或最高)的边。
  • 如果边是uv,检查uv 是否属于同一个集合。如果是,则从第 2 步开始不重复任何操作。
  • 如果没有联合,则存在 uv 的集合,即如果 u 在集合 A 中,而 v 在集合 B 中,则联合 A 和 B 作为 C,并丢弃 A 和 B。现在 u 和 @987654331 @ 属于 C。从第 2 步开始重复。

这是一个更好的代码: https://github.com/26prajval98/DSA/blob/master/graph%20algorithms/kruskal/main.c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多