并查集简介

1.Quick-find

Quick-find
import java.io.*;
import java.net.*;

//并查集
public class Temp {
    public static void main(String[] args){
        Quick_find a = new Quick_find(5);
        a.union(1,2);
        a.union(3,2);
        System.out.println(a.connected(1,2));
        System.out.println(a.connected(3,4));
        System.out.println(a.connected(1,3));
    }
}

class Quick_find {
    int id[];
    Quick_find(int N){
        id = new int[N];
        for(int i = 0;i<N;++i){         //初始化id
            id[i] = i;
        }
    }

    boolean connected(int p,int q){     //id是否相同,相同则连通
        return id[p]==id[q];
    }

    void union(int p ,int q) {          //将相关连通id更新
        int j = id[q];
        for(int i = 0;i<id.length;++i){
            if(id[i]==id[p])
                id[i] = j;
        }
    }
}

/*分析复杂度
* Initialize:O(N)
* Find:O(1)
* Union:O(N)	
* */

2.Quick-union

Quick-union

//id存储其“父结点”
class Quick_UnionUF {
    private int id[];

    Quick_UnionUF(int N) {
        id = new int[N];                  //id初始化
        for (int i = 0; i < N; ++i)
            id[i] = i;
    }

    int root(int i) {                    //get 根
        while (i != id[i])
            i = id[i];
        return i;
    }

    boolean connected(int p, int q) {     //根节点是否相同
        return root(p) == root(q);
    }

    void union(int p, int q) {          //根节点union
        int i = root(p);
        int j = root(q);
        if (i != j) id[i] = j;          //实际上根节点 j = id[j]
    }
}

/*复杂度分析
Initialize:O(N)
Find: O(N) -worst
Union:O(N*) -include time of finding obj 最坏即每次union都是N 出现tall tree,在某些时候快,因为只需要操作一个结点,但是查找可能会较长时间
 */

3.Weighted-QU

Weighted+QU
class WeightedQU {               //加权快速合并--小树并大树
    private int id[];
    private int sz[];        //表根所在树的obj个数

    WeightedQU(int N) {
        id = new int[N];
        sz = new int[N];
        for (int i = 0; i < N; ++i) {
            id[i] = i;
            sz[i] = 1;                      //每个所在树结点为1
        }
    }

    int root(int i) {                       //get 根
        while (i != id[i])
            i = id[i];
        return i;
    }


    boolean connected(int p, int q) {      //same of QU,判断根结点是否同
        return root(p) == root(q);
    }

    void union(int p, int q) {
        int i = root(p);
        int j = root(q);

        if (sz[i] == sz[j]) {
            id[i] = j;      //小树根合并
            sz[j] += sz[i];
        }
        if (sz[i] < sz[j]) {
            id[i] = j;
            sz[j] += sz[i];
        } else {
            id[j] = i;
            sz[i] += sz[j];
        }
    }
}

/*复杂度分析
Initialize:O(N)
Find:lgN
Union:lgN* -include time of finding obj

简述:只有当一棵树>另一棵树的size时,depths会增加,所以没增加一层就会倍增size,n^k = N ==> depths = k = lgN ;
 */

4.Pathcopression-WeightedQU

Path compression+Weighted+QU

class Path_compression_WeightedQU{       //路径压缩+加权+快速合并
    private int id[];
    private int sz[];        //表根所在树的obj个数

    Path_compression_WeightedQU(int N) {
        id = new int[N];
        sz = new int[N];
        for (int i = 0; i < N; ++i) {
            id[i] = i;
            sz[i] = 1;                      //每个所在树结点为1
        }
    }

    int root(int i) {                       //get 根
        while (i != id[i]) {
            id[i] = id[id[i]];              //每次合并会调用root函数,则每一次合并将树"基本展平"-使之指向祖父结点
            i = id[i];
        }
        return i;
    }


    boolean connected(int p, int q) {      //same of QU,判断根结点是否同
        return root(p) == root(q);
    }

    void union(int p, int q) {
        int i = root(p);
        int j = root(q);

        if (sz[i] == sz[j]) {
            id[i] = j;      //小树根合并
            sz[j] += sz[i];
        }
        if (sz[i] < sz[j]) {
            id[i] = j;
            sz[j] += sz[i];
        } else {
            id[j] = i;
            sz[i] += sz[j];
        }
    }
}

/*复杂度分析
在最坏复杂度上边,压缩路径+加权+QU 之后复杂度接近线性 O(N+Mlg*N) ~ O(N + 5M)

    可以认为lg*N<5 because of lg*2^65536 = 5;(即取5次lg即将2^65536变为1)
 */

/*小总结
经证明,在并查集的算法中不存在线性算法
algorithm & worst-case time
    quick-find      M*N
    quick-union     M*N
    weighted+QU     N+MlogN
path compression+QU N+MlogN
weighted+path+QU    N+Mlg*N
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值