并查集(Union-Find)算法

并查集(Union-Find)是解决动态连通性问题的一类非常高效的数据结构。

动态连通性

可以想象一张地图上有很多点,有些点之间是有道路相互联通的,而有些点则没有。如果我们现在要从点A走向点B,那么一个关键的问题就是判断我们能否从A走到B呢?换句话说,A和B是否是连通的。这是动态连通性最基本的诉求。现在给出一组数据,其中每个元素都是一对“点”,代表这对点之间是联通的,我们需要设计一个算法,让计算机依次读取这些数据,最后判断出其中任意两点是否连通。注意,并查集所涉及的动态连通性只是考虑“是否连通”这一二值判别问题,而不涉及连通的路径到底是什么。

举个例子,比如下图。为了简单起见,我们以整数 0~9 表示图中的10个点,然后给出两两连通的数据如下:[(4, 3), (3, 8), (6, 5), (9, 4), (2, 1), (8, 9), (5, 0), (7, 2), (6, 1), (6, 7)]

现在,“并”的操作可以这样来描述:观察第一个点对(4,3)(4,3),于是先找到点4和3,发现所在组别不一样,再将点4和3的组别都变成3(当然都变成4也行,这个随意设计),然后就产生了如下的表:

element 0 1 2 3 4 5 6 7 8 9
group number 0 1 2 3 3 5 6 7 8 9

推荐一个写的很不错的博客:https://blog.csdn.net/Hacker_ZhiDian/article/details/60965556

 

为了方便自己以后复习,参考这个博客自己写了一个Java版的代码

public class bingchaji {

	static int N=10;
	static int[] f=new int[N];
	static int [] high=new int[N];
	
	public static void main(String[] args) {
		int [][] m=new int[4][2] ;
		init();
		merge(1,3);
		merge(2,4);
		merge(3,4);
		merge(1,4);
		merge(5,6);
		
		for(int num:f) {
			System.out.println(num);
		}
				
	}
	//将所有点的“祖先”都设置为自己的 id ,
	static void init() {
		for(int i=1;ihigh[t2]) {
				f[t2]=t1;
			}else {
				f[t1]=t2;
				// 如果当前两个圈的高度相等,那么合并之后的圈高度要加一
				if(high[t1]==high[t2]) {
					high[t2]++;
				}
			}
		}
	}
	
	
}

 

你可能感兴趣的:(算法的友尽之旅)