并查集算法

这几天博主在看并查集算法,整理了一下:

我自己花了几个图,不好看大家将就一下,欢迎大家评论留言探讨学习。

这个班级有1,2,4三位同学,开始他们谁都不认识谁,但是毕竟都是同学总是要混个脸熟不是?

 

 1     public void union(int n,int m) {
 2         n=find(n);
 3         m=find(m);
 4         if(n!=m) 
 5             friend[n]=friend[m];
 6     }
 7     public int find(int n) {
 8         if(friend[n]==0) 
 9             friend[n]=n;
10         return friend[n];
11     }    

开始啊,1他谁都不认识,但是他可以推销自己,也就是friend[1]他就是1,2也是这个样子,两个人成为朋友总要有个人先开口,这不就2先开口了,那么friend[2]=friend[1],也就是2认识1了。

变成了这样:

 

后来啊这个班里的同学都认识了,成为了一个小圈子,但是年级里还有别的班级,这个时候出现了班级B:

 

班级A的代表是1,班级B的代表是3。这一天4和5这两个小同学吧眉来眼去他们呢好上了,他们就想着让自己的朋友也都彼此认识一下,这个时候出现了状况,friend[4]本来是1了,friend[5]是3了,怎么可以让他们都成为同一个代表呢?5是男孩子他就去找了他的联系人3,而3恰好就是班级B的老大,3觉得既然以后是朋友了,我让你1当老大也没什么。于是

本来应该是这个关系的顺序,因为4不想新认老大变成了这样!

 1     public void union(int n,int m) {
 2         n=find(n);
 3         m=find(m);
 4         if(n!=m) 
 5             friend[n]=friend[m];
 6     }
 7     public int find(int n) {
 8         if(friend[n]==0) 
 9             friend[n]=n;
10         else {
11             int x=friend[n];
12             if(friend[n]!=n)
13                 friend[n]=find(x);
14         }
15         return friend[n];
16     }

这个时候他们就处在同一个圈子里了。

但是吧,5和3说这件事的时候呢,6不在场,所以6的标记还是3。

也就是6->3->1这条路并没有遍历过,反观5->3->1已经遍历过了,所以5的编号已经是1,6却只能等有人需要从他这里认识他的联系人的时候,他才能变成1,也就是直接汇报。

 

posted @ 2019-04-25 15:35  你说你好  阅读(195)  评论(0编辑  收藏  举报