首页 > 编程语言 > 详细

最小生成树(MST)——Kruskal算法

时间:2015-03-25 12:19:12      阅读:213      评论:0      收藏:0      [点我收藏+]

      Kruskal算法是在处理一个森林——树的集合。开始时将图的每个顶点看做一棵树(集合),然后采用贪婪策略,每次从所有边中依次选出(Find)权值最小的边,当改边的两个端点不在同一集合时,则将终点所在集合与起点集合合并(Union),直到依次处理完所有的边,算法终止,此时所有的顶点在一个树中,即为最小生成树。

其基本步骤如下图所示:

技术分享                技术分享

               图一:初始时刻,所有顶点在各自集合中                                                                                      图二:选择最小权值边AD,将集合A与集合D合并

技术分享                技术分享

                                  图三:选择边CE,将集合C与集合E合并                                                                      图四:选择边BE,将集合ABDF与集合EC合并

技术分享

            图五:选择边EG,将集合G与集合ABCDEF合并。完成,所有点在同一集合中


实现代码:

<span style="color:#333333;">#include <stdio.h>
#include <stdlib.h>

#define INF 0x7fffffff

struct Graph
{
 int v;//顶点数
 int e;//边数
 int graph[][MAX];//边权重数组
};

struct Edge
{
	int s;//边起点
	int m;//边终点
	int w;//边权值
};

//将边按权值从小到大进行堆排序
void HeapSort(struct Edge* E);

int Kruskal(Graph G,int n)
{
	int i,j,sum=0;
	int* vset=(int*)malloc(n*sizeof(int));//标识每个顶点所属的集合
	struct Edge* E=(struct Edge*)malloc((n-1)*sizeof(Edge));//边数组

	for(i=0;i<n;++i)
		vset[i]=i;
	for(i=0;i<n-1;++i)
		for(j=0;j<n-1;++j)
		{
			E[i].s=i;
			E[i].m=j;
			E[i].w=G.graph[i][j];
		}

	HeapSort(E);//排序
	int sv;//记录起点所属集合
	int mv;//记录终点所属集合

	for(i=0;i<n-1;++i)//每次按权值大小,取出一条未处理的边
	{
		sv=vset[E[i].s];
		mv=vset[E[i].m];
		//边两端点不在同一集合,且两点确实连通
		if(sv!=mv && G.graph[E[i].s][E[i].m]<INF)
		{
			printf("%d to %d : %d /n",E[i].s,E[i].m,E[i].w);
			sum+=G.graph[E[i].s][E[i]].w;
			for(j=0;j<n-1;++n)//集合合并:将终点及其集合中的所有其他顶点移到起点所在集合
				{
					if(vset[j]==mv)
						vset[j]=sv;
			     }
		}
	}
	free(vset);
	free(E);
	return sum;
}</span>


                

最小生成树(MST)——Kruskal算法

原文:http://blog.csdn.net/yuyixinye/article/details/44618213

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!