路径压缩——并查集的第四种优化【Java版】(递归与非递归版本)

/**
*【路径压缩】处理并查集中的深的结点
* 对find方法进行优化
* 路径压缩中时间复杂度近乎为O(1)
*就是让当前结点指向自己父亲的父亲,减少深度
*非递归的路径压缩
*路径压缩也可以采用基于集合中元素的个数而非深度来
*/

public class UnionFind5 {
    private int count;
    private int[] parent;
    private int[] rank;
    public UnionFind5(int n) {
        count=n;
        parent=new int[n];
        rank=new int[n];
        for(int i=0;i<count;i++) {
            parent[i]=i;
            rank[i]=1;
        }
    }
    public boolean isConnected(int p,int q) {
        return find(p)==find(q);
    }
    int find(int p) {
        while(p!=parent[p]) {
            //路径压缩,让当前结点指向自己父亲的父亲
            parent[p]=parent[parent[p]];
            p=parent[p];
        }
        return p;
    }
    public void union(int p,int q) {
        int pRoot=find(p);
        int qRoot=find(q);
        if(pRoot==qRoot)
            return;
        if(rank[pRoot]>rank[qRoot]) {
            parent[qRoot]=pRoot;
        }else if(rank[pRoot]<rank[qRoot]) {
            parent[pRoot]=qRoot;
        }else {
            parent[qRoot]=pRoot;
            rank[pRoot]+=1;
        }
    }
    //测试数组
            public void printParent() {
                for(int a:parent)
                    System.out.print(a+" ");
                System.out.println();
            }

}

/**
* 递归的路径压缩
* 时间要比非递归的慢
*/

public class UnionFind6 {
    private int count;
    private int[] parent;
    private int[] rank;
    public UnionFind6(int n) {
        count=n;
        parent=new int[n];
        rank=new int[n];
        for(int i=0;i<count;i++) {
            parent[i]=i;
            rank[i]=1;
        }
    }
    public boolean isConnected(int p,int q) {
        return find(p)==find(q);
    }
    int find(int p) {
        if(p!=parent[p])
            parent[p]=find(parent[p]);
        return parent[p];
    }
    public void union(int p,int q) {
        int pRoot=find(p);
        int qRoot=find(q);
        if(pRoot==qRoot)
            return;
        if(rank[pRoot]>rank[qRoot]) {
            parent[qRoot]=pRoot;
        }else if(rank[pRoot]<rank[qRoot]) {
            parent[pRoot]=qRoot;
        }else {
            parent[qRoot]=pRoot;
            rank[pRoot]+=1;
        }
    }
    //测试数组
            public void printParent() {
                for(int a:parent)
                    System.out.print(a+" ");
                System.out.println();
            }

}

猜你喜欢

转载自blog.csdn.net/yulutian/article/details/79735801