Kruskal算法



Kruskal算法中,集合A是一个森林,其结点就是给定图的结点。每次加入到集合A中的安全边永远是权重最小的连接两个不同分量的边。在Prim算法中,集合A则是一棵树。每次加入到A中的安全边永远是连接AA之外某个结点的边中权重最小的边

 

Kruskal算法找到安全边的办法是,在所有连森林中两棵不同的树的边里面,找到权重最小的边(u, v)。设C1C2为边(u, v)所连接的两棵树。由于边(u, v)一定是连接C1和其他某棵树的一条轻量级边,边(u, v)是C1的一条安全边Kruskal算法属于贪心算法,因为它每次都选择一条权重最小的边加入到森林。

 

Kruskal算法实现

Kruskal实现过程中,使用一个不相交集合数据结构来维护几个互不相交的元素集合。每个集合代表当前森林中的一棵树。通过FindSet(u)来返回包含元素u集合的代表元素,通过Union来合并两棵树。

Kruskal算法_第1张图片



#include <stdio.h>
#include <stdlib.h>

#define BUFSIZE 100
#define VERTEXS 10
typedef struct {
	int u;
	int v;
	int weight;
} edge;
edge e[BUFSIZE] = {{'a', 'b', 4}, {'a', 'h', 8}, {'b', 'c', 8},
	{'b', 'h', 11}, {'c', 'd', 7}, {'c', 'f', 4}, {'c', 'i', 2},
	{'d', 'e', 9}, {'d', 'f', 14}, {'e', 'f', 10}, {'f', 'g', 2},
	{'g', 'i', 6}, {'g', 'h', 1}, {'i', 'h', 7}}; // forest

edge A[VERTEXS-1]; // 最小生成树的边集
int parent[VERTEXS]; // 记录前驱
int cost = 0;
	
void MakeSet(int x)
{	
	parent[x] = 0;
}

int FindSet(int x)
{	
	while (parent[x] != 0) // 这里的判断parent[x]的初值有关
		x = parent[x];
	return x;
}
 
bool UnionSet(int x, int y, int w)
{
	if (x != y) { // x, y不相同,将y合并到x中
		parent[y] = x;
		return true;
	}

	return false;
}

void UnionSet(int x, int y)
{
	parent[y] = x;
}

int Compare(const void *a, const void *b)
{	
	return ((edge *)a)->weight - ((edge *)b)->weight;
}

int main()
{
	int n; // 边的个数
//	printf("Please enter the number of edges:");
//	scanf("%d", &n);
//  输入边的信息
// 	for (int i = 0; i < n; i++) {
// 		scanf(("%c %c %d"), &(e[i].u), &(e[i].v), &(e[i].weight));
// 		getchar();
// 		e[i].u -= 'a';
// 		e[i].v -= 'a';
// 	}

	n = 14;
	for (int i = 0; i < BUFSIZE; i++) {
		MakeSet(i);
	}
	// sort the edges of E into nondecreasing order by weight
	int cnt = 0; // A中元素个数(边数)
	qsort(e, n, sizeof(edge), Compare);
	for (int i = 0; i < n; i++) { 
		int x = FindSet(e[i].u);  // 判断u、v是否属于同一棵树
		int y = FindSet(e[i].v);  // 如果是就会形成环
		if (x != y) { 
			A[cnt].u = e[i].u;
			A[cnt].v = e[i].v;
			A[cnt++].weight = e[i].weight;
			UnionSet(e[i].u, e[i].v); // 将y合并到x中
			printf("%c---%c:%d\n", e[i].u, e[i].v, e[i].weight);
			cost += e[i].weight;
		}
	}
	printf("Total weight:%d\n", cost);

	system("pause");
	return 0;
} 


你可能感兴趣的:(Kruskal算法)