简介:并查集实质是一种树形的数据结构,一般用于处理一些不相交集合的合并及查询问题。在具体问题解决上,比如找公共祖先节点、检查图的连通性等等,用通俗点的语言来描述的话,例如一个帮派(有点社会呀),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]);//将当前指针指向它的父节点 } }