一.基本操作:
1.查询元素属于的集合; 2.两个集合 合并为一。
集合的表示方法: [ 代表元 ] 法。选择固定元素表示集合。
集合的归属关系的表示方法:1.维护数组f [ x ],存每个元素对应集合的代表。
2.fa [ x ] 储存x的父亲节点。合并时,只需要连接两个树根。
二.路径压缩:
在FIND-SET操作中,把查找路径上的每个结点都直接指向根结点。
路径压缩并不改变结点的秩。关于路径压缩,之间为FIND-SET操作前集合,
之后为FIND-SET操作后集合。此时,查找路径上的每一个结点都直接指向根。
路径压缩代码实现方式有两种:递归式和非递归式。
void find_father(int x){
return fa[x]==0?x:fa[x]=find_father(fa[x]);
}
非递归式:
int find(int x){
int k, j, r;
r = x;
while(r != parent[r]) //查找跟节点
r = parent[r]; //找到跟节点,用r记录下
k = x;
while(k != r) { //非递归路径压缩操作
j = parent[k]; //用j暂存parent[k]的父节点
parent[k] = r; //parent[x]指向跟节点
k = j; //k移到父节点
}
return r; //返回根节点的值
}
集合合并:
x=find_father(x);
y=find_father(y);
if(x!=y) fa[x]=y;
三.按秩合并:
给每个点一个秩,其实就是树高。
每次合并的时候都用秩小的指向秩大的,可以保证树高最高为log2(n)。
操作的时候,一开始所有点的秩都为1。在一次合并后,假设是点x和点y。
x的秩小。设点x秩为rank[x],将fa[x]指向y&#