首页 > 其他分享 >并查集优化

并查集优化

时间:2022-09-18 14:11:11浏览次数:93  
标签:idx int 查集 public ld2 ld1 优化 leader

并查集及其优化

并查集可以动态地连通两个点,可以非常快速判断两个点是否连通。假设存在 n 个节点,我们先将所有结点的 leader 标为自身;每次连接节点 i 和 j 时,我们可以将 i 的 leader 标记为 j ;每次要查询两个节点是否相连时,我们可以查找 i 和 j 的祖先是否最终为同一个。

并查集多用于无向图的关系判断。例如冗余连接中,需要删除一条边,来将有环无向图转换为无环无向图。循环遍历每条边,如果两个节点有共同的祖先,则删除该边即可。


简单并查集

public class UnionFind {
    int[] leader;
    int count;
    
    public UnionFind() {}
    public UnionFind(int size) {
        this.leader = new int[size];
        this.count = n;
        for (int i = 1; i < size; ++i) {
            leader[i] = i;
        }
    }
    
    public int getCount() {
        return this.count;
    }
    
    public int find(int idx) {
        while (idx != leader[idx]) {
            idx = leader[idx];
        }
        return idx;
    }
    
    public void union(int idx1, int idx2) {
        int ld1 = find(idx1), ld2 = find(idx2);
        if (ld1 == ld2) return;
        leader[ld1] = find(ld2);
        --count;
    }
}

对简单并查集进行优化

由于并查集是一颗树,查找效率和树高有关,尽量要保证树的高度低。

对简单并查集优化主要有两个方向:路径压缩、按秩合并。


路径压缩

理想情况:父节点下面直接连接着其子节点,且所有子节点都是叶子节点。

迭代方式:没有对中间节点的做leader节点做更新。

递归方式:修改了中间所有节点的leader节点。


public class UnionFind {
    //省略
    public int find1(int idx) {
        while (idx != leader[idx]) {
            idx = leader[idx];
        }
        return idx;
    }
    
    public int find2(int idx) {
        if (idx != leader[idx]) {
            leader[idx] = find(leader[idx]);
        }
        return leader[idx];
    }
}

按秩合并

秩:以当前节点为根的树的高度上限。秩初始化为0,合并两颗树时,对比他们的秩,秩较大的树为新的根节点,新父节点秩 += 1;

在union时,将秩小的树合并到秩大的树上。

只有根节点的秩有意义,非根节点的秩没有意义。

虽然秩由高度决定,但是我们不直接记录高度,因为树的高度在查找过程中可能会变。但秩代表的是上限,是不会变的,所以记录秩是更高效的做法。


public class UnionFind {
    public int[] leader;
    public int[] rank;
    public int count;
    
    public UnionFind() {}
    public UnionFind(int size) {
        this.count = size;
        this.leader = new int[size];
        this.rank = new int[size];
        for (int i = 1; i < size; ++i) {
            leader[i] = i;
        }
    }

    //省略
    
    public void union(int idx1, int idx2) {
        int ld1 = find(idx1), ld2 = find(idx2);
        if (ld1 == ld2) return;
        
        if (rank[ld1] < rank[ld2]) {
            leader[ld1] = ld2;
        } else if (rank[ld1] > rank[ld2] {
            leader[ld2] = ld1;
        } else {
            leader[ld1] = ld2;
            rank[ld2] += 1;
        }
        --count;
    }
}

最终优化版

public class UnionFind {
    public int[] leader;
    public int[] rank;
    public int count;
    
    public UnionFind(int size) {
        this.leader = new int[size];
        this.rank = new int[size];
        this.count = size;
        
        for (int i = 1; i < size; ++i) {
            leader[i] = i;
        }
    }
    
    public int getCount() {
        return this.count;
    }
    
    public int find(int idx) {
        if (idx != leader[idx]) {
            leader[idx] = find(leader[idx]);
        }
        return leader[idx];
    }
    
    public void union(int idx1, int idx2) {
        int ld1 = find(idx1), ld2 = find(idx2);
        if (ld1 == ld2) return;
        
        if (rank[ld1] < rank[ld2]) {
            leader[ld1] = ld2;
        } else if (rank[ld1] > rank[ld2]) {
            leader[ld2] = ld1;
        } else {
            leader[ld1] = ld2;
            ++rank[ld2];
        }
        --count;
    }
}

参考

标签:idx,int,查集,public,ld2,ld1,优化,leader
From: https://www.cnblogs.com/ogleede/p/16704727.html

相关文章

  • 算法中的最优化方法01
    算法中的最优化方法0100课程简介优化尽可能用最佳的方式处理一下事项计算机中基于优化的算法多准则控制器的设计模糊建模中的聚类机器人轨迹规划流程工业中的调度......
  • 第二十一章 MySQL数据库优化
    一、数据硬件优化(选型)1.数据库选择1.真实的硬件物理机,虚拟化,搭建数据库2.云服务器ECS,自己搭建数据库3.云数据库(RDS,DRDS)2.数据库类型1.OLTP 在线事务处理系统,支持大......
  • 您需要知道的 5 个网站优化工具
    您需要知道的5个网站优化工具说到网站优化工具,可以说越多越好。虽然这最终不是真的,但如果您想运行一个成功的网站,那么您肯定想要使用很多必需品。为什么?简单的。如果您......
  • MySQL教程 - 优化数据库
    更新记录转载请注明出处。2022年9月10日发布。2022年9月10日从笔记迁移到博客。优化数据库查看用户使用情况SHOWPROCESSLIST;杀连接进程killuserId;......
  • Day_1(并查集朋友圈、字典序排序)
    1.并查集朋友圈:找出最多的一个圈子内有多少用户!id[](表示当前节点的父节点)nodeNum[](表示当前节点为根的那一组节点数量)importjava.util.Scanner;//并查集class......
  • linux 内核参数优化
    linux内核参数优化//允许非本地Ip地址socket监听net.ipv4.ip_nonlocal_bind=1//开启ipv4转发net.ipv4.ip_forward=1//是否开启数据包时间戳net.ipv4.tcp_time......
  • dp线段树优化
    题目:PottedFlowerDescriptionThelittlecattakesoverthemanagementofanewpark.Thereisalargecircularstatueinthecenterofthepark,surroundedby......
  • 第 22 题:介绍下重绘和回流(Repaint & Reflow),以及如何进行优化
    1.浏览器渲染机制浏览器采用流式布局模型(FlowBasedLayout)浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了渲染树(RenderTree)。有了RenderTree,我们......
  • Gitea 1.17.2 | 带来视觉提升、完善资源校验、加强安全性等42项优化
    Gitea1.17.2合并了42个PullRequest,现已正式发布,我们建议所有用户升级到此版本。您可以到阅读原文了解更详细的介绍。致谢:@zeripath为Gitea贡献了诸多安全补丁!......
  • GANs的优化函数与完整损失函数计算
    生成对抗网络(GANs)近年来在人工智能领域,尤其是计算机视觉领域非常受欢迎。随着论文“GenerativeAdversarialNets”[1]的引入,这种强大生成策略出现了,许多研究和研究项目......