图论--kruskal算法

本文详细介绍了kruskal算法的C语言实现过程,包括代码实现、案例演示以及算法运行结果分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kruskal算法

 

代码实现:c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LEN 20
#define INTMAX 0xFFFF
#define TRUE 1
#define FALSE 0

typedef char type[MAX_LEN];
int          father[MAX_LEN];
int          son[MAX_LEN];
int          visit[MAX_LEN];
int          TreeSum;

typedef struct Kruskal{
    int     x;
    int     y;
    int     value;
}Kruskal[MAX_LEN];

typedef struct MGraph{

    type    verticse[MAX_LEN];
    int     vexnum;
    int     arcnum;
    int     weight[MAX_LEN][MAX_LEN];
}MGraph;

void CreateGraph( MGraph * g , Kruskal edge )///---------------建立无向图
{
    int i , j , k , weight;
    type v1 , v2;
    printf("请输入顶点数和边数:\n");
    scanf("%d %d",&g->vexnum , &g->arcnum);
    printf("请输入每个顶点的信息:\n");
    for( i = 0 ; i < g->vexnum ; i ++ )
        scanf("%s",&g->verticse[i]);
    for( i = 0 ; i < g->vexnum ; i ++ )
        for( j = 0 ; j < g->vexnum ; j ++ )
            g->weight[i][j] = INTMAX;
    printf("请输入%d 的两两关系 及 权重:\n", g->arcnum);
    for( k = 0 ; k < g->arcnum ; k ++ ){
        scanf("%s %s %d",&v1 , &v2 , &weight);
        i = LocateVex( g , v1 );
        j = LocateVex( g , v2 );
        edge[k].x = i;
        edge[k].y = j;
        edge[k].value = weight;
        g->weight[i][j] = g->weight[j][i] = weight;
    }
}

int LocateVex( MGraph * g , type v )///----------匹配
{
    int i;
    for( i = 0 ; i < g->vexnum ; i ++ )
        if( (strcmp(v , g->verticse[i])) == 0 )
            return i;
}

void Visit( MGraph * g )///----------访问初始化
{
    int i;
    TreeSum = 0;
    for( i = 0 ; i < g->vexnum ; i ++ )
    {
        visit[i] = FALSE;
        father[i] = i;
        son[i] = 1;
    }
}

void Kruskal_TREE( Kruskal edge , MGraph * g )///---------------KRUSKAL算法--------------
{
    int root1 , root2;
    int i , e , ltotal = 0;
    Visit( g );
    for( i = 0 ; i < g->arcnum ; i ++ )
    {
        e = GetWeight( edge , g );
        root1 = Find( edge[e].x );
        root2 = Find( edge[e].y );
        if( root1 != root2 ){
            ltotal ++;
            TreeSum += edge[e].value;
            UnionSets( root1 , root2 );
            printf("%s <--> %s  (%d)\n",g->verticse[edge[e].x] , g->verticse[edge[e].y] , edge[e].value);
        }
        if( ltotal == g->vexnum - 1 )
            break;
    }
    if( ltotal != g->vexnum - 1 )
        printf("\nhave piont not in the tree!\n\n");
    printf("-------------------kruskal----end----------------------------------------\n");
}

int GetWeight( Kruskal edge , MGraph * g )///--------------------获取权值最小的边-------------------
{
    int i ,temp = INTMAX , k ;
    for( i = 0 ; i < g->arcnum ; i ++ )
        if( !visit[i] && edge[i].value < temp ){
            k = i;
            temp = edge[k].value;
        }
    visit[k] = TRUE;
    return k;
}

int Find ( int x )///--------------------查找父亲节点
{
    return x == father[x]? x : Find(father[x]);
}

void UnionSets( int root1 , int root2)///----------------合并
{
    if (son[root1] >= son[root2])    // 按个数求并(个数用负数表示)。
    {
        son[root2] += son[root1];
        father[root1] = root2;
    }
    else
    {
        son[root1] += son[root2];
        father[root2] = root1;
    }
}

int main()///---------------------main()
{
    int i , T;
    printf("------------------------kruskal算法-------------------------\n");
    printf("请输入测试数据组数:\n");
    scanf("%d",&T);
    while( T-- ){
        MGraph g;
        Kruskal edge;
        CreateGraph( &g , edge );
        printf("\n-----------------测试--------------------------------\n");
        for(i = 0 ; i < g.arcnum ; i ++ )
            printf("x = %d y = %d value = %d\n",edge[i].x, edge[i].y ,  edge[i].value);
        Kruskal_TREE( edge , &g );
        printf("\n-------------------------------------------------\n\n");
    }
    return 0;
}


 

案例:

------------------------kruskal算法-------------------------
请输入测试数据组数:
3
请输入顶点数和边数:
5 4
请输入每个顶点的信息:
1 2 3 4 5
请输入4 的两两关系 及 权重:
1 2 3
1 3 2
2 4 3
3 5 6

-----------------测试--------------------------------
x = 0 y = 1 value = 3
x = 0 y = 2 value = 2
x = 1 y = 3 value = 3
x = 2 y = 4 value = 6
1 <--> 3  (2)
1 <--> 2  (3)
2 <--> 4  (3)
3 <--> 5  (6)
-------------------kruskal----end----------------------------------------

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值