并查集的实现与优化

并查集的实现与优化

LeetCode上有一道名为朋友圈的题目,如下:

班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。

给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。

读完题目要求,暂时能想到的是,如果要解决该问题,首先要判断出在这N名学生中谁跟谁是朋友关系,其次是,对于关系的划分,有哪些学生属于这一组,而哪些学生属于另外一组。那基本的数据组织和数据操作该如何实现呢?

并查集,作为一种用于解决不相交集的合并及查询问题的树型数据结构,非常适合用来处理类似于上述例子的问题。顾名思义,并查代表着两种不同的操作,用来表示合并两个不同集合的操作,用来表示检索两个不同元素是否属于同一个集合。

如果按照并查集的定义进行数据结构和数据操作的声明,那就有了以下代码实现

typedef struct UnionSet {
   
	int *data;
	int n;
} UnionSet;

UnionSet *initUnionSet(int n) {
   
	UnionSet *u = (UnionSet *)malloc(sizeof(UnionSet));
	u->n = n;
	u->data = (int *)malloc(sizeof(int) * (n + 1));
	for ( int i = 0; i < n; i++ ) {
   
		u->data[i] = i;
	}
	return u;
}

int find(UnionSet *u, int x) {
   
	return u->data[x];
}

void merge(UnionSet *u, int a, int b) {
   
	int fa = find(u, a), fb = find(u, b);
	if ( fa
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值