union-find 算法

union-find :用于解决触点之间的连通性问题,有一下三种算法。

/**
 * QuickFind 快速查找法
 * 特点:能够以常数级的时间查找某一触点在哪个分量, 但是在最坏的情况下连接的花费是平凡级的。
 *
 * 成员变量:数组arr、分量数count(数组的索引表示各个触点、数组的值表示各个触电所在的分量)
 * 私有方法:
 * 公开方法:联合 union、查找分量 find、是否联通 connection
 * 要求:触电不能重复,以int来表示各触点。
 */
public class QuickFind {
    private int[] arr;
    public int count;

    public QuickFind(int n) {
        arr = new int[n];
        for(int i=0;i<n;i++){
            arr[i]=i;
        }
        this.count = n;
    }

    public void union (int p,int q){
        if(connection(p,q))return;
        int numq = arr[q];
        int nump = arr[p];
        for(int i=0;i<arr.length;i++){
            if(arr[i] == numq){
                arr[i] = nump;
            }
        }
        count--;
    }

    public int find(int p){
        if(p>=0&&p<arr.length) return arr[p];
        return -1;
    }

    public boolean connection(int p, int q){
        if(find(p)==find(q)) return true;
        return false;
    }
}
/**
 * 快速联合方法  Quick Union
 * 特点:对于查找分量的花费与连接的深度有关、但是连接的花费是常数据的
 *
 * 成员变量:数组arr、分量数count(数组的索引表示各个触点、数组的值表示各个触电与那个触点连接)
 * 私有方法:
 * 公开方法:联合 union、查找分量 find、是否联通 connection
 * 要求:触电不能重复,以int来表示各触点。
 */
public class QuickUnion {
    private int[] arr;
    public int count;

    public QuickUnion(int n) {
        arr = new int[n];
        for(int i=0;i<n;i++){
            arr[i]=i;
        }
        this.count = n;
    }

    public int find(int p){
        if(p>=0&&p<arr.length) {
            while(arr[p]!=p){
                p=arr[p];
            }
            return p;
        };
        return -1;
    }

    public boolean connection(int p, int q){
        if(find(p)==find(q)) return true;
        return false;
    }

    public void union (int p,int q){
        if(connection(p, q)) return;
        //将q触点所在分量根节点连接到p所在分量,实现了将原来q触点所在分量的所有触点与q触电所在分量连接
        arr[find(q)] = p;
        count--;
    }
}

/**
 *  加权快速联合方法
 *  特点:是触点的平均深度减小,以减少find查询的花费
 */
class WeightedQuickUnion{
    private int[] arr;
    //加权数组,访问到根触点后,通过weight数组获取当前分量的大小
    //然后将小分量连接到大分量
    private int[] weight;
    public int count;

    public WeightedQuickUnion(int n) {
        arr = new int[n];
        weight = new int [n];
        for(int i=0;i<n;i++){
            arr[i]=i;
            weight[i]=1;
        }
        this.count = n;
    }

    public int find(int p){
        if(p>=0&&p<arr.length) {
            while(arr[p]!=p){
                p=arr[p];
            }
            return p;
        };
        return -1;
    }

    public boolean connection(int p, int q){
        if(find(p)==find(q)) return true;
        return false;
    }

    public void union (int p,int q){
        int rootp = find(p);
        int rootq = find(q);
        if(rootp==rootq) return;
        if(weight[rootp]<weight[rootq]) arr[rootp]=rootq;
        else arr[rootq]=rootp;
        count--;
    }
}
/**
 * 测试案例
 */
public class TestCase {
    public static void main(String[] args) {
        QuickFind quickFind = new QuickFind(10);
        quickFind.union(4,3);
        quickFind.union(8,3);
        quickFind.union(5,6);
        quickFind.union(4,9);
        quickFind.union(2,1);
        quickFind.union(5,0);
        quickFind.union(7,2);
        quickFind.union(6,1);
        System.out.println(quickFind.count);
        System.out.println(quickFind.find(9));
        System.out.println(quickFind.connection(4,2));
        System.out.println("=======================");
        QuickUnion quickUnion = new QuickUnion(10);
        quickUnion.union(4,3);
        quickUnion.union(8,3);
        quickUnion.union(5,6);
        quickUnion.union(4,9);
        quickUnion.union(2,1);
        quickUnion.union(5,0);
        quickUnion.union(7,2);
        quickUnion.union(6,1);
        System.out.println(quickUnion.count);
        System.out.println(quickUnion.find(9));
        System.out.println(quickUnion.connection(2,4));
        System.out.println("=========================");
        WeightedQuickUnion weightedQuickUnion = new WeightedQuickUnion(10);
        weightedQuickUnion.union(4,3);
        weightedQuickUnion.union(8,3);
        weightedQuickUnion.union(5,6);
        weightedQuickUnion.union(4,9);
        weightedQuickUnion.union(2,1);
        weightedQuickUnion.union(5,0);
        weightedQuickUnion.union(7,2);
        weightedQuickUnion.union(6,1);
        System.out.println(weightedQuickUnion.count);
        System.out.println(weightedQuickUnion.find(9));
        System.out.println(weightedQuickUnion.connection(2,4));
    }
}


//结果
2
8
false
=======================
2
8
false
=========================
2
8
false

猜你喜欢

转载自www.cnblogs.com/youzoulalala/p/11090894.html