SW练习_union_find算法

带权重的union_find可以有效降低树的高度,从而提高效率

package com.company;

/**
 * meng3.wei
 * 2020.02.16
 * 带权重的union-find
 * 带权重,可以保证小的树会被挂在大的树上,以保证树不会太高(随机挂载由于树的高度问题,性能会变低)
 */
public class UnionFind {
    private int count;//连通分量的个数
    private int[] pid;//保存父亲连接节点的id
    private int[] sonSize;//保存各个节点作为根节点的分量大小

    public UnionFind(int N){
        count=N;
        pid=new int[N];
        sonSize=new int[N];
        for (int i = 0; i < N; i++) {
            pid[i]=i;
            sonSize[i]=1;
        }
    }

    /**
     * 将p和q链接起来
     * @param p
     * @param q
     */
    public void union(int p,int q){
        int m=find(p);
        int n=find(q);
        if(m==n){//两个点的顶级父节点相同,则这两个点已经是联通的
            return;
        }
        pid[n]=m;//n的父亲节点改成m
        //if(sonSize[m]>=sonSize[n]){//m是大树,n是小树,小树n需要挂到大树m上
         //   pid[n]=m;//n的父亲节点改成m
         //   sonSize[m]=sonSize[m]+sonSize[n];
       // }else {
        //    pid[m]=n;
        //    sonSize[n]=sonSize[n]+sonSize[m];
        //}
        count--;
    }

    /**
     * 判断p和q是否连接
     * @param p
     * @param q
     * @return
     */
    public boolean connected(int p,int q){
        int m=find(p);
        int n=find(q);
        return m==n;
    }

    /**
     * 找个这个节点的顶级父节点
     * @param p
     * @return
     */
    public int find(int p){
        int temp=p;//先用temp保存下当前的节点p,因为p一会要变成p的顶级根节点
        while(pid[p]!=p){
            p=pid[p];
        }

        while(pid[temp]!=p){//路径压缩一下,都挂在顶级根节点上
            int a=temp;
            temp=pid[temp];
            pid[a]=p;//一路上的节点,都挂在顶级根节点p上
        }

        return p;
    }
    public int count(){
        return count;
    }
}

参照了以下代码,但是还尚有不理解的地方

https://blog.csdn.net/dm_vincent/article/details/7655764

https://blog.csdn.net/niushuai666/article/details/6662911

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值