三、内功算法之连通性问题快速合并优化

版权声明:话不在多,在于精 https://blog.csdn.net/qq_29857681/article/details/88787930

问题:为避免生成很高得树,影响节点查询性能。

处理:合并时,判断树高,将小树合并在大树下。

代码实现

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];
        }

    }
}

猜你喜欢

转载自blog.csdn.net/qq_29857681/article/details/88787930