并查集的功能基本上就在他名字里了。
并是指合并两个集合,查是指查找该元素属于哪个集合。
用我看过的一篇文章来描述每一个江湖门派就是一个集合,底下不管有多少帮众,他们的头的头…最终头头就是掌门人,并查集的查就是查掌门人,并就是并两个帮派。
用father[i]来表示i的父亲结点,若father[i]==i,它就是掌门人,很容易得出查的操作:
int findfather(int k){ int x=k while(x!=father[x]){ x=father[x]; } return x; }
下面讲并,两个帮派怎么合并,人员统计来统计去太麻烦,干脆让一个掌门人认另一个掌门人做小弟就完事了,于是有:
void unionit(int a,int b){ int i=findfather(a),j=findfather(b); father[j]=i; }
如果要对该门派进行路径压缩,提高查的效率,考虑到时间问题,如果每一个帮众都直接指向掌门人,一切就简单了,这就叫路径压缩:
int findfather(int k){ //路径压缩后的查 int x=k while(x!=father[x]){ x=father[x]; } while(k!=x){ int i=father[k]; father[k]=x; k=i; } return x; }
当然有递归实现,但是如果考虑到路径压缩为了时间效率的话,最好还是写迭代模式好一点。
该方法在数据结构中最小生成树判断是否产生环很有用