当前位置: 首页 > news >正文

并查集路径压缩

并查集里的 find 函数里可以进行路径压缩,是为了更快速的查找一个点的根节点。对于一个集合树来说,它的根节点下面可以依附着许多的节点,因此,我们可以尝试在 find 的过程中,从底向上,如果此时访问的节点不是根节点的话,那么我们可以把这个节点尽量的往上挪一挪,减少数的层数,这个过程就叫做路径压缩。

如下图中,find(4) 的过程就可以路径压缩,让数的层数更少。

节点 4 往上寻找根节点时,压缩第一步,树的层数就减少了一层:

节点 2 向上寻找,也不是根节点,那么把元素 2 指向原来父节点的父节点,操后后树的层数相应减少了一层,同时返回根节点 0。

find 过程代码修改为 :

// 查找过程, 查找元素p所对应的集合编号
// O(h)复杂度, h为树的高度
private int find(int p){assert( p >= 0 && p < count );// path compression 1while( p != parent[p] ){parent[p] = parent[parent[p]];p = parent[p];}return p;}

上述路径压缩并不是最优的方式,我们可以把最初的树压缩成下图所示,层数是最少的。

这个 find 过程代表表示为:

...
// 查找过程, 查找元素p所对应的集合编号
// O(h)复杂度, h为树的高度
private int find(int p) {assert (p >= 0 && p < count);//第二种路径压缩算法if (p != parent[p])parent[p] = find(parent[p]);return parent[p];
}
...

Java 实例代码

UnionFind3.java 文件代码:

package runoob.union;/*** 基于rank的优化*/
public class UnionFind4 {private int[] rank;   // rank[i]表示以i为根的集合所表示的树的层数private int[] parent; // parent[i]表示第i个元素所指向的父节点private int count;    // 数据个数// 构造函数public UnionFind4(int count){rank = new int[count];parent = new int[count];this.count = count;// 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合for( int i = 0 ; i < count ; i ++ ){parent[i] = i;rank[i] = 1;}}// 查找过程, 查找元素p所对应的集合编号// O(h)复杂度, h为树的高度private int find(int p){assert( p >= 0 && p < count );// 不断去查询自己的父亲节点, 直到到达根节点// 根节点的特点: parent[p] == pwhile( p != parent[p] )p = parent[p];return p;//第二种路径压缩算法//if( p != parent[p] )//parent[p] = find( parent[p] );//return parent[p];}// 查看元素p和元素q是否所属一个集合// O(h)复杂度, h为树的高度public boolean isConnected( int p , int q ){return find(p) == find(q);}// 合并元素p和元素q所属的集合// O(h)复杂度, h为树的高度public void unionElements(int p, int q){int pRoot = find(p);int qRoot = find(q);if( pRoot == qRoot )return;if( rank[pRoot] < rank[qRoot] ){parent[pRoot] = qRoot;}else if( rank[qRoot] < rank[pRoot]){parent[qRoot] = pRoot;}else{ // rank[pRoot] == rank[qRoot]parent[pRoot] = qRoot;rank[qRoot] += 1;   // 维护rank的值}}
}

http://www.lryc.cn/news/194240.html

相关文章:

  • spring和springMVC的说明
  • 软件工程与计算总结(十)软件体系结构设计与构建
  • 【实操】基于ChatGPT构建知识库
  • ribbonx编程笔记-读写注册表与使用自定义对话框
  • 网工记背配置命令(3)----POE配置示例
  • 网络安全(黑客技术)—0基础学习手册
  • [部署网站]01安装宝塔面板搭建WordPress
  • Can We Edit Multimodal Large Language Models?
  • 使用jsqlparser创建MySQL建表语句
  • 字符串思维题练习 DAY6 (CF 245H , CF 559B , CF 1731C , CF1109B)
  • Linux:Mac VMware Fusion13以及CentOS7安装包
  • 【微服务部署】十、使用Docker Compose搭建高可用Redis集群
  • 【数据结构】树状数组C++详解
  • 机器人制作开源方案 | 扫地机器人
  • 10.2手动推导linux中file, cdev, inode之间的关系
  • JavaScript基础知识13——运算符:一元运算符,二元运算符
  • 异步使用langchain
  • 抖音开放平台第三方代小程序开发,授权事件、消息与事件通知总结
  • 华为9.20笔试 复现
  • 二十五、【色调调整基础】
  • Android Studio SDK manager加载packages不全
  • [esp32-wroom]基础开发
  • 利用Docker 实现 MiniOB环境搭建
  • 【DB2】—— 数据库表查询一直查不出来数据
  • 【教程】使用vuepress构建静态文档网站,并部署到github上
  • python 机器视觉 车牌识别 - opencv 深度学习 机器学习 计算机竞赛
  • Hadoop3教程(十二):MapReduce中Shuffle机制的概述
  • MySQL为什么用b+树
  • 浅谈机器学习中的概率模型
  • MySQL 函数 索引 事务 管理