问题:为避免生成很高得树,影响节点查询性能。
处理:合并时,判断树高,将小树合并在大树下。
代码实现
package com.jd.testjava.algorithm;
/**
* 连通性问题
* 使用树结构实现
* 快速合并算法优化(将小树合并到大树下面,避免大树合并到小树,高度成倍增长)
* 带权(高度)快速合并算法
*
* @author lichenyang8
* @date 2019/3/25
*/
public class QuickUnionAlgorithmPlus implements IAlgorithm{
private int[] ids;
private final int length;
//统计树高
private int[] sz;
/**
* 初始化数组
* @param length
*/
public QuickUnionAlgorithmPlus(int length){
this.length = length;
ids = new int[length];
sz = new int[length];
for (int i = 0; i < length; i++) {
ids[i] = i;
sz[i] = 1;
}
}
/**
* 查询根节点
* 自己的根节点等于自身,则为根节点
*/
private int getRoot(int p){
while (ids[p] != p){
//查询父节点得根节点
p = ids[p];
}
return p;
}
/**
* 查询是否联通
* 根节点相同则为联通
*/
@Override
public Boolean isConnect(int p, int q){
return getRoot(p) == getRoot(q);
}
/**
* 连通两个节点
* @param p
* @param q
*/
@Override
public void connect(int p, int q){
//获得p的根
int pid = ids[p];
int qid = ids[q];
if (pid == qid) return;
//sz[pid] 表示p所在树的高度
if (sz[pid] < sz[qid]){
/**
* 小树合并到大树
*/
//将pid的根换成qid
ids[pid] = qid;
//维护以qid为根的树高
sz[qid] += sz[pid];
}else{
ids[qid] = pid;
sz[pid] += sz[qid];
}
}
}