一、并查集概念

  • 并查集是一种树形的数据结构,顾名思义,它用于处理一些不交集的合并及查询问题。 它支持两种操作:

    • 查找(Find):确定某个元素处于哪个子集,单次操作时间复杂度 O(α(n)),即查询元素p和元素q是否属于同一组
    • 合并(Union):将两个子集合并成一个集合,单次操作时间复杂度 O(α(n)),即合并元素p和元素q所在的组
  • 以下是并查集的常用模板,需要熟练掌握。其中:
    • n 表示节点数
    • p 存储每个点的父节点,初始时每个点的父节点都是自己
    • size 只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
    • find(x) 函数用于查找 x 所在集合的祖宗节点
    • union(a, b) 函数用于合并 a 和 b 所在的集合

二、并查集模板

1、模板一

// 并查集类。需要维护一个数组和两个方法,find()和union()
class UnionFind {
constructor(n) {
this.arr = []
// 初始默认为每个人是独立圈子,则他的父级就是他自身
for (let i = 0; i < n; i++) {
this.arr[i] = i
}
} // 直到arr[x] === x,停止向上搜索
find(x) {
let arr = this.arr
while (arr[x] !== x) {
x = arr[x]
}
return arr[x]
} // 路径压缩
union(x, y) {
let xFather = this.find(x)
let yFather = this.find(y)
if (xFather !== yFather) {
this.arr[xFather] = yFather
}
}
}

2、模板二

class UnionFind {
constructor(size) {
this.fa = []
this.size = size
this.init()
}
// 初始化 每个元素的父节点为自身
init() {
for(let i = 0; i < this.size; i++) {
this.fa[i] = i
}
}
// 递归找到根节点,同时进行路径压缩
find(x) {
if(x === this.fa[x]) {
return x
}
this.fa[x] = this.find(this.fa[x])
return this.fa[x]
}
// 合并 x, y 直到各自的根节点, 其中一个的指向另一个
merge(x, y) {
let fx = this.find(x)
let fy = this.find(y)
if(fx !== fy) {
this.fa[fx] = fy
}
}
// 获取集合数量
getCount() {
let count = 0
for(let i = 0; i < this.size; i++) {
if(this.fa[i] === i) {
count++
}
}
return count
}
}

3、模板三

// 这个并查集使用了一种叫做路径压缩的优化策略,可以有效减少查找操作的时间复杂度
class UnionFind {
    constructor(n) {
        this.count = n;
        this.parent = [];
        this.rank = [];
        for (let i = 0; i < n; i++) {
            this.parent[i] = i;
            this.rank[i] = 1;
        }
    }     // 查找元素 p 所在的集合编号
    find(p) {
        if (p !== this.parent[p]) {
            this.parent[p] = this.find(this.parent[p]);
        }
        return this.parent[p];
    }     isConnected(p, q) {
        return this.find(p) === this.find(q);
    }     // 将元素 p 和元素 q 所在的集合合并
    unionElements(p, q) {
        const pRoot = this.find(p);
        const qRoot = this.find(q);
        if (pRoot === qRoot) {
            return;
        }
        if (this.rank[pRoot] < this.rank[qRoot]) {
            this.parent[pRoot] = qRoot;
        } else if (this.rank[qRoot] < this.rank[pRoot]) {
            this.parent[qRoot] = pRoot;
        } else {
            this.parent[pRoot] = qRoot;
            this.rank[qRoot] += 1;
        }
    }
}

三、力扣例题

四、PDF参考资料

百度网盘:https://pan.baidu.com/s/1FzPwQKEEoSeEWFX-7A104A?pwd=hcfr

数据结构与算法 -> 并查集的更多相关文章

  1. 模板——最小生成树kruskal算法+并查集数据结构

    并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...

  2. 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集

    最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...

  3. 近期公共祖先(LCA)——离线Tarjan算法+并查集优化

    一. 离线Tarjan算法 LCA问题(lowest common ancestors):在一个有根树T中.两个节点和 e&sig=3136f1d5fcf75709d9ac882bd8cfe0 ...

  4. BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1123  Solved: 408 题目连接 http://w ...

  5. POJ1861 Network (Kruskal算法 +并查集)

    Network Description Andrew is working as system administrator and is planning to establish a new net ...

  6. [学习笔记]可持久化数据结构——数组、并查集、平衡树、Trie树

    可持久化:支持查询历史版本和在历史版本上修改 可持久化数组 主席树做即可. [模板]可持久化数组(可持久化线段树/平衡树) 可持久化并查集 可持久化并查集 主席树做即可. 要按秩合并.(路径压缩每次建 ...

  7. 图论 Kruskal算法 并查集

    #include<iostream> #include<cstring> #include<string> #include<cstdio> #incl ...

  8. poj1251 Jungle Roads Kruskal算法+并查集

    时限: 1000MS   内存限制: 10000K 提交总数: 37001   接受: 17398 描述 热带岛屿拉格里山的首长有个问题.几年前,大量的外援花在了村庄之间的额外道路上.但是丛林不断地超 ...

  9. 数据结构 之 并查集(Disjoint Set)

    一.并查集的概念:     首先,为了引出并查集,先介绍几个概念:     1.等价关系(Equivalent Relation)     自反性.对称性.传递性.     如果a和b存在等价关系,记 ...

  10. luoguP3367 [模板]并查集

    题目链接:https://www.luogu.org/problemnew/show/P3367 思路: 今天学了新算法——并查集,本题是简单的并查集题的模板. 核心思想是“递归+压缩路径”. 并查集 ...

随机推荐

  1. 35.ListSerializer详解

    ListSerializer继承了BaseSerializer 一般情况下我们不直接使用ListSerializer ListSerializer会自动调用,序列化many=True的字段时,会自动调 ...

  2. python dir函数解析

    dir() 函数  不带参数,直接执行是返回当前环境中对象的名称列表.指定对象的名称作为参数执行,返回指定对象当中的属性(包括函数名,类名,变量名等)   下面我们具体找几个例子测试一下  dir() ...

  3. C# 7.0 添加和增强的功能【基础篇】

    C# 7.0 版是与 Visual Studio 2017 一起发布. 虽然该版本继承和发展了C# 6.0,但不包含编译器即服务. 一.out 变量 以前我们使用out变量必须在使用前进行声明,C# ...

  4. Microsoft Office for Mac最新版本安装教程,亲测可用!!!

    办公必备的Office工具,它为需要使用 Office 工具的用户和企业设计,让他们可以利用功能强大的 Outlook 来处理电子邮件.日历和通讯录事宜.你所熟知和信赖的 Office 经过更新后,可 ...

  5. 四、Pod 介绍

    一.什么是 Pod ​Pod 是 kubernetes 集群中最小的部署和管理的基本单元,协同寻址,协同调度. ​Pod 是一个或多个容器的集合,是一个或一组服务(进程)的抽象集合. ​Pod 中可以 ...

  6. Ubuntu实现电商网站+Mysql主从复制+NFS

    Ubuntu实现电商网站+Mysql主从复制+NFS 1.环境准备 提前准备:Mysql8.0.30安装包.Mysql安装脚本.shopxo2.3.0安装包.DNS脚本 服务器 IP地址 作用 系统版 ...

  7. 编辑距离(Minimum Edit Distance)

    编辑距离(Minimum Edit Distance,MED),也叫 Levenshtein Distance.他的含义是计算字符串a转换为字符串b的最少单字符编辑次数.编辑操作有:插入.删除.替换( ...

  8. Vivado_8位流水灯

    Design 代码中的计数器设置是因为我的开发板的时钟是100MHZ的,也就是1秒完成了100_000_000次时钟信号,所以我设置计数器为100_000_000次. 也就是说,我让流水灯的变化周期为 ...

  9. C# 获取打开的EXCEL中某列的行数

    背景 在通过C#操作EXCEL时 获取行数 int iRowCount = worksheet.get_Range("A65535", oMissing).get_End(MExc ...

  10. java学习之JSP

    0x00前言 JSP:全拼写:java Server pages:java 服务器端页面 可以理解为一个特殊的页面:可以定义html代码也可以定义java的代码 定义:JSP是简化Servlet编写的 ...