Union-Find 算法
Union-Find 算法,也就是常说的并查集算法,主要是解决图论中「动态连通性」问题的。
(以下仅是记录笔记,是学习他人资料的时候记录的,如有不严谨的地方多包容)
要实现的地方
1、连接
2、判断两点是否连通
3、计算有多少连通分量
其他函数
public int find(int x) {
//通过一直寻找父亲节点,找到最上边的根节点,因为根节点的父亲还是自己
while (x != parent[x]) {
x = parent[x];
}
return x;
}
public void union(int p, int q) {
//第一步寻找两个节点的根,如果相同则证明在同一连通分量上
int rootp = find(p);
int rootq = find(q);
if(rootp == rootq) {
return ;
}
//无向的,直接连接并减少连通分量
parent[rootp] = rootq;
count--;
}
public int count() {
return count;
}
public boolean connected(int p, int q) {
int rootp = find(p);
int rootq = find(q);
return rootp == rootq;
}
树的平衡性优化
因为直连会导致出现极端情况,即一条直线,这时时间复杂度较高。
为防止出现这种情况,我们其实是希望,小一些的树接到大一些的树下面,这样就能避免头重脚轻,更平衡一些。
如图:
可以考虑增加一个数组存储每个节点对应的所连节点数,这样再稍加修改union函数,时间复杂度降为O(N),众所周知这样的降幅是非常大的。