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

本文深入解析Kruskal算法用于寻找无向图的最小生成树的过程,通过逐步演示算法步骤,并提供具体实现代码,帮助读者理解算法逻辑及其实现细节。

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

      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>


                

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值