【算法4】1.5.union-find算法

1.5 union-find 算法

union-find 算法用于检查两个触点是否属于同一分量。

union-find 算法 API:

public class UF {
    UF(int N); // 以整数标识(0 到 N-1) 初始化 N 个触点

    void union(int p, int q); // 在 p 和 q 之间添加一条连接
    int find(int p); // p 所在的分量的标识符
    boolean connected(int p, int q); // p 和 q 是否属于同一个分量
}

union-find 算法实现一

  • 初始化时,所有触点处于不同的分量
  • 每添加一条连接 p-q 时,遍历数组,将属于 pid 的分量归并到 qid 的分量中
/**
 * union-find 算法
 * */
public class UnionFind {
    private int[] id;
    private int count;

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

    public UnionFind(In in) {
        this(in.readInt());
        int N = count;
        for (int i = 0; i < N; i++) {
            union(in.readInt(), in.readInt());
        }
    }

    // union-find 算法实现
    public void union(int p, int q){
        int pID = find(p);
        int qID = find(q);
        if (pID == qID) return;

        for (int i = 0; i < id.length; i++) {
            if (id[i] == pID) {
                id[i] = qID;
            }
        }
        count--;
    }

    public int find(int p) {
        return id[p];
    }

    public boolean connected(int p, int q) {
        return find(p) == find(q);
    }

    public int count() {
        return count;
    }
}

union-find 实现二:优化 union() 方法

  • 初始化时,所有的触点属于不同的分量
  • 每次添加一条连接 p-q 时,将 p 连接到 q 的分量中(即 id[p] = id[q]),分量的根触点 q[id] == q
// union-find 算法实现
public void union(int p, int q){
    int pID = find(p);
    int qID = find(q);
    if (pID == qID) return;

    id[pID] = id[qID];
    count--;
}

// 从 id[p] 所属分量的根,即 id[p] = p
public int find(int p) {
    while (id[p] != p) {
        p = id[p];
    }
    return p;
}
posted @ 2022-05-31 20:08  廖子博  阅读(28)  评论(0编辑  收藏  举报