定义
并查集顾名思义就是有“合并集合”和“查找集合中的元素”两种操作的关于数据结构的一种算法
算法辅助数组parent
用集合中的某个元素来代表这个集合,该元素称为集合的代表元。
一个集合内的所有元素组织成以代表元为根的树形结构。
对于每一个元素 parent[x]指向x在树形结构上的父亲节点。如果x是根节点,则令parent[x] = x。
对于查找操作,假设需要确定x所在的的集合,也就是确定集合的代表元。可以沿着parent[x]不断在树形结构中向上移动,直到到达根节点。
判断两个元素是否属于同一集合,只需要看他们的代表元是否相同即可
并查集简单实例
数据:
1代表连通,0代表不连通
1,1,0,1,0,
1,1,0,0,0,
0,0,1,0,1,
1,0,0,1,0,
0,0,1,0,1.
public class 并查集 {
static int[] parent;
// 初始化数组,将数组中每个元素的前驱结点置为自己
static int[] init(int[] pre) {
for(int i = 0 ; i < pre.length ; i++)
pre[i] = i;
return pre;
}
// 查找前驱的函数,不带路径压缩
static int find(int x) {
return parent[x] == x ? x : find(parent[x]);
}
// 查找前驱的函数,带路径压缩
static int find_Path_Compression(int x) {
int k = x;
while (x != parent[x]) x = parent[x];
while (k != x) {
int z = parent[k];
parent[k] = x;
k = z;
}
return x;
}
// 合并函数,具体合并规则根据题意而定
static void join(int i, int j) {
int fi = find(i);
int fj = find(j);
if(fi < fj)
parent[fj] = fi;
else
parent[fi] = fj;
}
public static void main(String[] args) {
int[][] matrix = new int[][] {{1,1,0,1,0},{1,1,0,0,0},{0,0,1,0,1},{1,0,0,1,0},{0,0,1,0,1}};
parent = new int[matrix.length];
parent = init(parent);
for(int i = 0 ; i < matrix.length ; i++)
for(int j = 0 ; j < matrix.length ; j++)
if(matrix[i][j] == 1)
join(i, j);
for(int i : parent)
System.out.print(i + " ");
}
}
输出:
0 0 2 0 2
注意
在和合并函数中,判断完合并条件后,进行parent数组修改的时候要注意是:
是将父结点索引修改而不是子结点
if(fi < fj)
parent[fj] = fi;
else
parent[fi] = fj;
而不是
if(fi < fj)
parent[j] = fi;
else
parent[i] = fj;
计算连通分量的时候可以使用判断条件,条件成立则连通分量数加一
parent[i] == i