您的位置:首页 > 其它

图论--kruskal算法

2012-10-22 22:58 567 查看
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----------------------------------------

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 tree 测试 struct