并查集
并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题,主要用于解决一些元素分组的问题。判断是否产生回路要用到并查集,关于并查集只介绍它在本算法中的应用。并查集中保存了一棵或者几棵树,这些树有这样的特点:通过树中一个结点,可以找到其双亲结点,进而找到根结点(其实就是之前讲过的树的双亲存储结构)。这种特性有两个好处: - -是可以快速地将两个含有很多元素的集合并为一个。两个集合就是并查集中的两棵树,只需找到其中一棵树的根,然后将其作为另一棵树中任何一个结点的孩子结点即可。二是可以方便地判断两个元素是否属于同一个集合。通过这两个元素所在的结点找到它们的根结点,如果它们有相同的根,则说明它们属于同一个集合,否则属于不同集合。并查集可以用一维数组来简单地表示。图7-13所示即为并查集在数组中的表示及合并过程。
public class DisjointSetUnion {
private int[] dsu;
public DisjointSetUnion(int n) {
this.dsu = new int[n + 1];
for (int i = 1; i <= n; i++) { // 合并前各自为政
this.dsu[i] = i;
}
}
/**
* 认爹过程,查找节点 v 的根节点
*/
public int getUnionRoot(int v) {
if (dsu[v] == v) {
return v;
}
// 查询过程中的路径压缩,降低每个节点与根节点的路径长度
dsu[v] = getUnionRoot(dsu[v]);
return dsu[v];
}
/**
* u 和 v 不属于同一个团伙才可合并返回true结果
*/
public boolean mergeUnion(int v, int u) {
// 两个团伙合并时,要经过各自的老大来实现
int t1 = getUnionRoot(v);
int t2 = getUnionRoot(u);
if (t1 != t2) {
dsu[t2] = dsu[t1]; // 让 t2 归顺于 t1 节点
return true;
}
return false;
}
public int[] getDsu() {
return dsu;
}
}
并查集—解密犯罪团伙: https://blog.csdn.net/wtyvhreal/article/details/43494647
算法学习笔记(1) : 并查集: https://zhuanlan.zhihu.com/p/93647900/
数据结构--并查集(Disjoint-Set):https://michael.blog.csdn.net/article/details/105294270
浙公网安备 33010602011771号