数据结构--实现求最小生成树的克鲁斯卡尔算法(c语言)

#include <stdio.h>
#define MAX 20

typedef struct
{
    char Shi, Mo;  //边的起始点
    int weight;     //边的权值
}Edge;

typedef struct
{
    char Ding[MAX];         //存放顶点信息
    Edge edge[MAX];         //存放边的信息
    int dingnum, biannum;   //顶点数,边数
}EdgeGraph;

void Create(EdgeGraph* M)
{
    scanf("%d %d", &M->dingnum, &M->biannum);        //输入顶点数,弧数
    for (int i = 0; i < M->dingnum; i++)            //输入顶点的值
        scanf("%c", &M->Ding[i]);
    for (int i = 0; i < M->biannum; i++) {          //输入每条边的始末,权值
        scanf("(%c,%c,%d)", &M->edge[i].Shi, &M->edge[i].Mo, &M->edge[i].weight);
    }
}

void Pai(EdgeGraph* M)              //利用冒泡排序,将每条边按权值由小到大排序
{
    
    for (int i = 0; i < M->biannum - 1; i++)
        for (int j = i + 1; j < M->biannum; j++) {
            if (M->edge[i].weight > M->edge[j].weight) {
                
                Edge temp = M->edge[i];
                M->edge[i] = M->edge[j];
                M->edge[j] = temp;
            }
        }
}

int Findding(EdgeGraph* M, char ding)               //寻找当前顶点在顶点数组中的下标
{
    for (int i = 0; i < M->dingnum; i++) {
        if (ding == M->Ding[i])
            return i;
    }
    return -1;
}

int FindRoot(int t, int parent[])           //寻找当前结点的根节点
{
    while (parent[t] > -1)
        t = parent[t];
    return t;
}

void Kruskal(EdgeGraph* M)
{
    int num=0;
    int root1, root2;       //第一个顶点与第二个顶点的根结点
    int ding1, ding2;
    int parent[MAX];
    Pai(M);
    for (int i = 0; i <= M->dingnum; i++)      //初始化每个根节结点
        parent[i] = -1;
    for (int i = 0; i < M->biannum; i++) {
        ding1 = Findding(M, M->edge[i].Shi);        //找到起始点在数组中下标
        ding2 = Findding(M, M->edge[i].Mo);         //找到末尾点在数组中下标
        root1 = FindRoot(ding1, parent);            //通过下标,求该结点的根节点
        root2 = FindRoot(ding2, parent);

        if (root1 != root2) {                   //若根节点不同,则输出,且num++
            printf("(%c,%c,%d,1)", M->edge[i].Shi, M->edge[i].Mo, M->edge[i].weight);
            parent[root2] = root1;              //连接两个结点
            num++;
        }
        else
            printf("(%c,%c,%d,0)", M->edge[i].Shi, M->edge[i].Mo, M->edge[i].weight);
        
        if (num == M->dingnum - 1) {                //当已经连接的边数=顶点数-1时,结束算法
            while (i<biannum){                      //输出剩下的边
                i++;
                printf("(%c,%c,%d,0)", M->edge[i].Shi, M->edge[i].Mo, M->edge[i].weight);
            }
            return ;
        }
    }
}

main()
{
    EdgeGraph* M = (EdgeGraph*)malloc(sizeof(EdgeGraph));
    Create(M);
    Kruskal(M);
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值