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----------------------------------------