union-find算法

Api:

public class UF{
  UF(int N);//初始化N个触点
  void union(int p,int q) //在p和q之间添加一条连接
  int find(int p) // p所在的分量的标识符
  boolean connected(intp ,int q)//如果q和p在同一各分量中则返回true
  int count()//联通分量的数量
}

加权quick-union算法:
将小数的根节点连接到大树的根节点

public class WeightedQuickUnionUF{
    private int[] id;
    private int[] sz;
    private int count;

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

    public int getCount() {
        return count;
    }

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

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

    public void union(int p, int q) {
        int i = find(p);
        int j = find(q);
        if (i == j) return;
        if (sz[i] < sz[j]) {
            id[i] = j;
            sz[j] += sz[i];
        } else {
            id[j] = i;
            sz[i] += sz[j];
        }
        count--;
    }
}

最优解法:路径压缩的加权quick-union算法
要实现路径压缩,只需要为find()添加一个循环,将在路径上遇到的所有节点都直接链接到根节点。

    public int find(int p) {
        int root = p;
        while (root != id[root]) root = id[root];
        while (p!=root) {
            int next = id[p];
            id[p] = root;
            p = next;
        }
        return root;
    }

你可能感兴趣的:(union-find算法)