并查集简单实现

并查集

​ 在一些应用中我们会对一堆元素进行分组,每一个小组是一个不相交的集合。然后我们会根据需要查找某一个元素属于那个集合,或者是将某两个元素所在的集合按照一定要求进行合并。就好比朋友圈一样:A 与 B 原本不认识,各自有各自的朋友圈。但是有一天偶然之间 A 与 B 朋友圈里的一位朋友 C 在聚会时认识了。C:“回头我介绍我的大哥 B 给你认识吧”,随后 A 和 B 都带着自己的小弟们碰面了。于是AB两个朋友圈合二为一了。
在这里插入图片描述

给他们六个依次编号为1~6,用一个数组 array[] 来记录他们的关系,数组的下标 i 表示第 i 个人,array[i] 表示 i 的父亲,如果 i 为根的话,则 array[i] 为负,array[i] 的绝对值表示以该节点为根的树总共拥有的节点个数:

在这里插入图片描述

整个变化过程 首先是找各自的 root (find(A),find(B)),然后就是合并两个集合 union(A,B)。很形象称为并查集。使用代码实现并查集:

public class UnionFindSet {
    private List<Integer> set;

    public UnionFindSet(){
        set = new ArrayList<>(16);

    }

    public UnionFindSet(int size){
        set = new ArrayList<>(size);
    }

    /**
     * 查找元素编号为 index 的集合根。
     * @param index
     * @return
     */
    public int findRoot(int index){
        while (set.get(index)>=0){
            index = set.get(index);
        }
//        采用路经压缩
//        if (set.get(index)<0) return index;
//        if (set.get(index)>=0)
//            set.set(index,findRoot(set.get(index)));
//        return set.get(index);
        return index;
    }

    /**
     * 合并 a,b 所在集合
     * @param a
     * @param b
     * @return
     */
    public boolean union(int a,int b){
        int aRoot = findRoot(a);
        int bRoot = findRoot(b);
        if (aRoot==bRoot) return false;

        set.set(aRoot,set.get(aRoot)+set.get(bRoot));
        set.set(bRoot,aRoot);
        return true;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值