并查集的几种实现方式(java版)

并查集:Union Find :一种不一样的树形结构:由孩子指向父亲

用处:网络中节点间的连接状态,路径问题,朋友问题。

对于一组数据,主要支持两个动作:

  union(p,q)

  isConnected(p,q)

并查集的几种实现方式(java版)_第1张图片

上面代表的是数字,下面代表的是 id值,这样可以明显看到,0到4属于同一个集合,5到9属于第二个集合。因为各自的id值相等 

并查集的几种实现方式(java版)_第2张图片

 

并查集的几种实现方式(java版)_第3张图片

 第一个并查集的实现方法:

 定义一个接口

public interface UF {
    int getSize();
    boolean isConnected(int p,int q);
    void unionElements(int p,int q);

}
import java.util.Scanner;

public class UnionFind implements UF {

    private int [] id ;//初始定义的数组

    public UnionFind(int size){
        id = new int[size];
        for (int i=0;i=id.length)
            throw new IllegalArgumentException("p is out of bound");
        return id[p];
    }
    //用于查看元素p和元素q是否属于同一个集合
    @Override
    public boolean isConnected(int p, int q) {
        return find(p)==find(q);
    }
    //合并元素
    @Override
    public void unionElements(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;
            }
        }
    }
}
class Main{
    public static void main(String[] args){
        Scanner sr = new Scanner(System.in);
        UnionFind u = new UnionFind(4);
            int a = sr.nextInt();
            int b = sr.nextInt();
//            int c = sr.nextInt();
            u.unionElements(a,b);
        System.out.println(u.find(a));
        System.out.println(u.find(b));
    }
        }

 

第二个方法用树来实现:

每一个节点都指向自己都是一棵树 :注意下面的值的变化,每次联合其实相当于去联合根节点

 并查集的几种实现方式(java版)_第4张图片

并查集的几种实现方式(java版)_第5张图片

 

 

 

 

并查集的几种实现方式(java版)_第6张图片

 并查集的几种实现方式(java版)_第7张图片

 并查集的几种实现方式(java版)_第8张图片

 并查集的几种实现方式(java版)_第9张图片

 

 查询这是就是log(h)h代表的深度,虽然牺牲了查询时间但是节省了合并时间

 

public interface UF {
    int getSize();
    boolean isConnected(int p, int q);
    void unionElements(int p, int q);

}
public class UnionFind2 implements UF{
    private int [] parent;//表示第i个元素指向那个节点
    public UnionFind2(int size){
        parent = new int[size];
        for (int i = 0; i 

 加入了节点的判断 这样非常省时间:

public interface UF {
    int getSize();
    boolean isConnected(int p, int q);
    void unionElements(int p, int q);

}
public class Main implements UF {
    private int [] parent;//表示第i个元素指向那个节点
    private int [] sz;//表示以sz[i]以i为根的集合中元素的个数
    public Main(int size){
        parent = new int[size];
        sz = new int [size];
        for (int i = 0; i 

 

你可能感兴趣的:(java数据结构,java算法)