Kruskal算法求最小生成树

1. 代码

 
#include<stdio.h>
#include<stdlib.h>
#define MAX_VEX 100
typedef struct
{
	int bv, ev, w;
}EDGE;
EDGE edgeset[MAX_VEX];//边集数组;edgnum<=MAX_VEX-1 
int creat()
{
	int edgnum, i;
	printf("输入边数:\n");
	scanf("%d", &edgnum);
	printf("输入边的起点,终点,权:\n");
	for(i=1;i<=edgnum;i++)
	{
		printf("(bv,ev,w)=");
		scanf("%d,%d,%d", &edgeset[i].bv, &edgeset[i].ev, &edgeset[i].w);
	}
	return edgnum;
}
//排序,使边集数组edgeset[]元素按权值递增顺序排列 
void sort(int edgnum)
{
	int i, j;
	EDGE t;
	for(i=1; i<=edgnum-1; i++)
		for(j=i+1;j<=edgnum; j++)
		{
			if(edgeset[i].w>edgeset[j].w) 
			{
				t=edgeset[i];
				edgeset[i]=edgeset[j];
				edgeset[j]=t;
			}
		}	
}
//寻找顶点属于的连通分量的根节点 
int seek(int set[MAX_VEX], int v)
{
	int root=v;
	while(set[root]>0)
		root=set[root];
	return root;
}
/*Kruskal算法 
1. 各顶点单独为连通分量
2. 按权值将各边排序,选取最小者,要求是起讫点不属于同一连通分量。 
使该边的起讫点合并为同一连通分量 。
3. 重复2,直至全部顶点属于同一连通分量 
*/
void kruskal(int edgnum)
{
	int i;
	int v1, v2;
	int set[MAX_VEX];
	for(i=1;i<MAX_VEX;i++)//i<=vexnum;这里没必要引入 vexnum
		set[i]=0;
	printf("输出最小生成树\n");
	i=0;//待获取的生成树的边在边集数组的下标 
	while(i++<edgnum)
	{
		v1=seek(set, edgeset[i].bv);
		v2=seek(set, edgeset[i].ev);
		if(v1!=v2)
		{
			printf("(%d,%d) %d\n", edgeset[i].bv, edgeset[i].ev, edgeset[i].w);
			set[v2]=v1;//或  set[v2]=v1;
		}	
	}  	
}
int main()
{
	int i, edgnum;
	edgnum=creat();
	sort(edgnum); 
	printf("按权值递增顺序输出边\nbv ev w\n");
	for(i=1;i<=edgnum;i++)
		printf("%d  %d  %d\n", edgeset[i].bv, edgeset[i].ev, edgeset[i].w);
	kruskal(edgnum);
 	return 0;
}

2. 结果

猜你喜欢

转载自blog.csdn.net/lituusliu/article/details/78078532