最小生成树-克鲁斯卡尔方法(Kruskal)-C语言实现

克鲁斯卡尔方法(Kruskal):不断将最小的但不会构成回路的边并入树。


示例如下:



判断是否构成回路要用到并查集,并查集可快速查找要并入的边与当前的树是否为同一集合(是否在同一棵树中),若为同一集合(在同一棵树中)则会构成回路。

并查集的实现方式为:并查集v[a]用来存放a的双亲结点,当a ==v[a]时为根节点,可通过语句"while(a != v[a]) a = v[a];"从a出发最终得到的a',为最初的a的根节点。当两个结点的根节点相同时a ==b,则产生回路。


C代码如下:

struct Road{		//简易的定义一条边
	int a, b;	//一条边的两个顶点
	int w;		//边的权值
};
Road road[m];
int v[maxSize] = {0};		//定义并查集数组

int getRoot(int a)		//在并查集中找根节点的函数
{
	while(a != v[a]) a = v[a];		//自己为自己双亲时,为根节点
	return a;
}

void Kruskal(MGraph g, int &sum, Road road[])	//克鲁斯卡尔方法
{
	int i, a, b;
	sum = 0;
	for(i = 0; i < g.n; ++i) 
   v[i] = i;	//各自为根节点(一棵树)
	sort(road, g.e);			//对所有边进行排序
	for(i = 0; i < g.e; ++i){	//排过序的边依次判断
		a = getRoot(road[i].a);
		b = getRoot(road[i].b);
		if(a != b){		//不同根时,将该边并入(此时不会形成回路)
			v[a] = b;	// b成为a的双亲结点
			sum += road[i].w;
		}
	}
}





  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是C语言实现最小生成树克鲁斯卡尔算法)的代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTICES 20 #define MAX_EDGES MAX_VERTICES * (MAX_VERTICES - 1) / 2 typedef struct { int u, v, w; } Edge; int parent[MAX_VERTICES]; Edge edge[MAX_EDGES]; int find(int u) { while (u != parent[u]) { u = parent[u]; } return u; } void union_set(int u, int v) { parent[u] = v; } void kruskal(int n, int m) { int i, j, count = 0; int min_cost = 0; for (i = 0; i < n; i++) { parent[i] = i; } for (i = 0; i < m; i++) { int u = edge[i].u; int v = edge[i].v; int w = edge[i].w; int p_u = find(u); int p_v = find(v); if (p_u != p_v) { union_set(p_u, p_v); min_cost += w; count++; if (count == n - 1) { break; } } } if (count == n - 1) { printf("Minimum cost of the spanning tree: %d\n", min_cost); } else { printf("No spanning tree exists.\n"); } } int main() { int n, m, i; printf("Enter the number of vertices: "); scanf("%d", &n); printf("Enter the number of edges: "); scanf("%d", &m); printf("Enter the edges (u, v, w):\n"); for (i = 0; i < m; i++) { scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w); } kruskal(n, m); return 0; } ``` 其中,`parent`数组用于实现并查集,`find`函数用于查找节点所在的集合,`union_set`函数用于将两个节点所在的集合合并。`kruskal`函数用于实现克鲁斯卡尔算法,其中`n`表示节点的个数,`m`表示边的个数,`edge`数组用于存储边的信息,包括起点、终点和权值。最后输出生成树的最小权值和。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值