# 第 1 版基于 quick-find 实现

重点提示:基于 id 的思想类似于:给每个元素改名字,名字一样,就表示在同一个集合中。

  • 优点:查询两个元素是否在一个集合中很快。
  • 缺点:把两个集合合并成一个集合较慢。

这一版「并查集」并不常用,仅作为了解。

并查集可以使用数组表示。这个数组我们命名为 id 。初始化的时候每一个元素的值都是不一样的。如果值一样的,表示是属于同一个集合内的元素。

基于 id 的 quick-find 的思路:设置 id 数组,数组的每个元素是分量标识。

从 quick-find 这个名字上看,我们这一版的实现,对于 find(int p) 这个操作来说是高效的,但对于 union(int p, int q) 这个操作是低效的,因为需要遍历整个并查集。find(int p) 这个操作的时间复杂度是 ,而 union(int p, int q) 这个操作的时间复杂度是 ,要全部遍历并查集中的元素,把其中一个分量标识的所有结点的编号更改为另一个一个分量标识。

例如上面的表格中,如果我们要将第 行的 01 执行 union(int p, int q) 操作,有两种方式:

  • 第 1 种方式:把第 1 行的 02468 的值全改成 1
  • 第 2 种方式:把第 1 行的 13579 的值全改成 0。

可以看到,union(int p, int q) 的操作和问题的规模成正比,所以 quick-find 思想(基于 id)的 union(int p, int q) 操作时间复杂度是

Java 代码:

public class UnionFind1 implements IUnionFind {

    private int[] id; // 分量 id

    private int count; // 连通分量的数量

    public UnionFind1(int n) {
        this.count = n;
        // 初始化分量 id 数组
        id = new int[n];
        for (int i = 0; i < n; i++) {
            id[i] = i;
        }
    }

    @Override
    public String versionName() {
        return "并查集的第 1 个版本,基于 id 数组,quick-find";
    }

    // 以常数时间复杂度,返回分量的标识符,与并查集的规模是无关的,这一步很快
    // 因此我们称这个版本的并查集是 quick-find
    @Override
    public int find(int p) {
        return id[p];
    }

    @Override
    public boolean isConnected(int p, int q) {
        return find(p) == find(q);
    }

    // 因为需要遍历数组中的全部元素,所以这个版本其实效率并不高
    @Override
    public void union(int p, int q) {
        int pid = find(p);
        int qid = find(q);

        // 如果 p 和 q 已经在相同的分量之中,则什么都不做
        if (pid == qid) {
            return;
        }

        // 将 p 的分量重新命名为 q 的名称
        for (int i = 0; i < id.length; i++) {
            if (find(i) == pid) {
                id[i] = qid;
            }
        }
        // 每次 union 以后,连通分量减 1
        count--;
    }
}

使用数组 id 在进行 union(int p, int q) 的时候,要遍历整个数组中的结点,这种方式效率不高,因此,我们换一种思路:由于 union(int p, int q) 慢,所以我们就想办法让 union(int p, int q) 快起来。


作者:liweiwei1419 链接:https://suanfa8.com/union-find/quick-find 来源:算法吧 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Last Updated: 11/19/2024, 1:33:17 AM