简介:并查集实质是一种树形的数据结构,一般用于处理一些不相交集合的合并及查询问题。在具体问题解决上,比如找公共祖先节点、检查图的连通性等等,用通俗点的语言来描述的话,例如一个帮派(有点社会呀),a的大哥是b,b的大哥是c,c的大哥是d,此时a、b、c、d互相是不认识的,假如发生了帮派争斗,b和d相遇了,为了不伤到自己人,他们两个就必须确定对方是不是自己人,这个时候,b就问自己的大哥c,d是哪根葱,c反手就给b一个耳刮子,说,那是你大哥我的大哥,你想不想混啦,这个时候就可以确定b和d是一伙的了,而当a和d相遇时,又要问同样的问题,a要问自己的大哥b,并且这样一层层问上去,明显很麻烦,而且还有被打的危险,这时候并查集就出现了,d老大哥说,以后你们不要乱认大哥了,帮派里就我一个大哥,你们都直接单线跟我联系就行啦。不知道这样解释能不能懂。在数据结构中,就是将当前节点的指针都指向根节点(我感觉用指针更好理解)。
具体代码如下:
class Main {
static int head [];
public static void main(String[] args) {
int relationship [][]={{1,2},{2,3},{3,4}};
head=new int [5];
for(int i=1;i<=4;i++)
head[i]=i;//建立指针,没有给定关系之前直接指向自己
for(int i=0;i<3;i++) {
int a=relationship[i][0];
int b=relationship[i][1];
u(a,b);
}
for(int i=1;i<=4;i++)//路径压缩,将所有有关联的节点指向共同的祖先节点
f(i);
}
static void u (int a,int b) {
if(f(a)==f(b)) return;//是同一父节点直接返回
head[f(a)]=f(b);//不然,将a的指针指向b的父节点(这是一个递归的过程)
}
static int f(int i) {//f函数可以看作寻找父节点的方法
if(head[i]==i)//是当前的祖先节点就直接返回本身值,注意是当前
return i;
return head[i]=f(head[i]);//将当前指针指向它的父节点
}
}