并查集

并查集(Union-Find)是一种用来对元素进行分类与查找所在类的数据结构。

并查集主要有两个操作:

1. int find(int i):查找元素i所在的集合

2. void union(int i, int j):将元素i所在的集合和元素j所在的集合合并为一个集合

并查集最基本的思想是使用森林的数据结构来实现,在一开始所有元素都是一颗单独的树。当进行find查找操作时,返回这个元素所在树的根结点。当进行union合并操作时,将某个元素所在的树的根结点作为子结点连接到另一个元素中,这样就合并了两颗树,原来两个集合中的所有元素有了一个共同的根结点。

并查集还有两种常见的优化方法:路径压缩和按秩合并。

路径压缩

在执行find查找操作时,我们可以把此结点以及查找路径上的每个父结点都直接连接到根结点上,这样就压缩了树的深度,下次查找时可以直接以O(1)的时间复杂度执行find操作。

按秩合并

在执行union合并操作时,如果每次都将较小的树作为子树连接到另一颗较大的树上,则可以保持树的平衡,控制下次查询的耗时。秩是树的深度,可以反映树的大小,本文以秩来衡量树的大小进行合并。(如果使用了路径压缩优化,那么秩不能准确的反映树的深度,但是还是能反映树的大小,因此按秩合并优化与路径压缩优化不冲突)

java代码实现

public class UnionFind {

    private int[] parent;
    private int[] rank;

    public UnionFind(int n) {
        parent = new int[n];
        for (int i = 0; i < n; i++) parent[i] = i;
        rank = new int[n];
    }

    public int find(int i) {
        return parent[i] == i ? i : (parent[i] = find(parent[i]));
    }

    public void union(int i, int j) {
        int ri = find(i), rj = find(j);
        if (rank[ri] > rank[rj]) parent[rj] = ri;
        else parent[ri] = rj;
        if (rank[ri] == rank[rj] && ri != rj) rank[rj]++;
    }
}

源代码地址https://github.com/SSSxCCC/Algorithm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SSSxCCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值