[TOC]
Union-Find Set(这下听懂了)
基本
一个类似树的物理层实现,一个类的节点通过类似链表一样的link在一起
数组有效的是1~n,-1/0表示空
void Initialize(int n){
parent = new int [n + 1];
for(int i = 1; i <= n; i++){
parent[i] = 0;
}
}
int find(int e){
while(parent[e]){
e = parent[e];
}
return e;
}
void Union(int i, int j){
parent[j] = i;
}
优化
Weight rule
If the number of nodes in tree i is less than the number in tree j, then make j the parent of i; otherwise,make i the parent of j.
一言以蔽之,谁孩子多谁当爹
如果是root的话,parent就用来放他的整个树的节点个数
相对应的需要一个新的root数组来存放是否是root
void Initialize(int n){
root = new bool[n + 1];
parent = new int[n + 1];
for(int i = 1; i < n; i++){
root[i] = true;
parent[i] = 1;
}
}
int Find(int e){
while(!bool[e]){
e = parent[e];
}
return e;
}
void Union(int i, int j){
if(parent[i] < parent[j]){
parent[j] += parent[i];
parent[i] = j;
root[i] = false;
}
else{
parent[i] += parent[j];
root[j] = false;
parent[j] = i;
}
}
Height rule
If the height of tree i is less than that of tree j, then make j the parent of i; otherwise,make i the parent of j.
一言以蔽之,谁长谁当爹
root的parent放-height-1
void Initialize(int n){
parent = new int [n + 1];
for(int i = 1; i <= n; i++){
parent[i] = -1;
}
}
int Find(int e){
while(!parent[e]){
e = parent[e];
}
return e;
}
void Union(int i, int j){
if(parent[i] < parent[j]){
parent[j] = i;
}
else if(parent[i] == parent[j]){
parent[i]--;
parent[j] = i;
}//特别注意
else{
parent[i] = j;
}
}
Improvement
int Find(int e){
int j = e;
while(!root[j]){
j = parent[j];
}
int f = e;
while(f != j){
int pf = parent[f];
parent[f] = j;
f = pf;
}
return j;
}//非递归实现
public int find( int x ){
if( s[ x ] < 0 )
return x;
else
return s[ x ] = find( s[ x ] );
}//递归实现