并查集是一种树型的数据结构 ,并查集可以高效地进行如下操作:
1、查询元素p和元素q是否属于同一组
2、合并元素p和元素q所在的组
-- 设计思想:
1、eleAndGroup数组,索引为值,索引处保存的是其父节点,如果索引和值相等说明到达根结点
2、sz数组用于保存树中的元素个数,
3、合并的时候将较小的树,添加到较大的树中
-- API设计:
-- 代码:
public class UF_Tree_Weighted {
// 记录结点元素和该元素所在的父结点
private int[] eleAndGroup;
// 存储每个根结点对应的树中元素的个数
private int[] sz;
// 记录并查集中数据的分组个数
private int count;
// 初始化并查集
public UF_Tree_Weighted(int N) {
// 初始情况下,分组数量和元素数量相当
this.count = N;
// 初始化数组
eleAndGroup = new int[N];
sz = new int[N];
// 初始情况下i索引处存储的值就是i
for (int i = 0; i < N; i++) {
eleAndGroup[i] = i;
}
// 初始情况下数组中都为1
for (int i = 0; i < N; i++) {
sz[i] = 1;
}
}
// 获取当前并查集中的数据有多少个分组
public int count() {
return count;
}
// 元素p所在树的父结点
public int find(int p) {
while (true) {
// 如果元素p和父结点相等,说明找到根结点
if(p == eleAndGroup[p]) {
return p;
}
// 如果不是根结点,继续找其父结点
p = eleAndGroup[p];
}
}
// 把p元素所在分组和q元素所在分组合并
public void union(int p,int q) {
// 找到p元素所在的根结点
int pRoot = find(p);
// 找到q元素所在的根结点
int qRoot = find(q);
// 如果元素p和q已经在同一个树中,则无需合并
if(pRoot == qRoot) {
return;
}
// 将较小的树添加到较大的树上面
if(sz[pRoot] < sz[qRoot]) {
eleAndGroup[pRoot] = qRoot;
// 重新调整较大的树元素个数
sz[pRoot] += sz[qRoot];
}else {
eleAndGroup[qRoot] = pRoot;
sz[pRoot] += sz[qRoot];
}
// 分组数量-1
count--;
}
}
@ 以上内容属于个人笔记