并查集,一种比较基础的算法,主要是用于解决一些连通性的问题,通常这些问题不关心2个点A和B是怎么联通的、联通的路径是什么,而只是关心A和B是否联通。
从名称可以看出,对于并查集来说,最常见的2中操作是合并2个集合和查找某个元素归属的集合。
下面是并查集的最简单的实现:
int find(int a){
while(set[a]!=a){
a = set[a];
}
return a;
}
void merge(int a, int b){
a = find(a);
b = find(b);
if(a!=b){
set[a] = b;
}
}
上面的方法,在查询的时候,如果遇到最坏情况,每次都要遍历全部的元素,这显然是不能接受的,于是有了带路径压缩的查询方法:
int find(int a){
int b = a;
while(a!=set[a]){
a = set[a];
}
while(b!=a){
int temp = set[b];
set[b] = a;
b = temp;
}
return a;
}
路径压缩后,每次查询一个节点的根节点的时候,会把它本身和它的所有父节点(包括级联)直接挂到根节点下,这样下次再来查询的时候就可以提高速度和效率。