一、并查集概念

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

    • 查找(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. VSCode设置鼠标滚轮滑动设置字体大小

    1. 打开"文件->首选项->设置 2. 打开settings.json文件 3. 在setting.json 中添加"editor.mouseWheelZoom&qu ...

  2. 一、Go语言开篇介绍

    Go语言开篇介绍 Go语言 是Google公司 在2007开发一种静态强类型.编译型语言,并在 2009 年正式对外发布. Go语言以其近C的执行性能和近解析型语言的开发效率,以及近乎于完美的编译速度 ...

  3. k8s之pod连接被拒排查

    k8s之pod连接被拒排查 pod链接被拒 查看pod的时候发现pod的状态为crashloopbackoff 然后看看日志发现报错如下 kubectl -n kf10 logs easydata-r ...

  4. ubuntu 输入法IBUS 输入不成功问题

    ubuntu 输入法IBUS 输入不成功问题 只需要在 输入如下代码 -Xms128m -Xmx750m -XX:ReservedCodeCacheSize=240m -XX:+UseConcMark ...

  5. SpringBoot 06: springboot中使用redis

    配置SpringBoot 创建SpringBoot项目时勾选Redis起步依赖 <dependency> <groupId>org.springframework.boot&l ...

  6. php 高并发

    1 swoole的博客 http://rango.swoole.com/archives/508 2 消息队列 3 接口并发请求

  7. 树莓派(香橙派)通过.NET IoT 操作SPI编写屏幕驱动 顺手做个四足机器人(一)

    摘要 这片文章主要是记录自己的整活过程,涉及到的技术包括.NET IoT, .NET Web, .NET MAUI,框架采用的也是最新的.NET 7. 本人是用的树莓派Zero 2 W(ubuntu- ...

  8. A-深度学习面试题

    目录 目录 一,滤波器与卷积核 二,卷积层和池化输出大小计算 2.1,CNN 中术语解释 2.2,卷积输出大小计算(简化型) 2.3,理解边界效应与填充 padding 参考资料 三,深度学习框架的张 ...

  9. python3实现AES加密

    前言 这几天研究了一下 python 实现 AES 加密,有很多坑 AES 加密的参数及其条件 这个 AES 加密的主要坑就在于这些条件, 首先 aes 加密有一下几个参数 秘钥:加密的时候用秘钥,解 ...

  10. 数电第二周总结_by_yc

    数电第二周总结_CC 重点: 模块实例化.仿真测试.数值表示.参数.表达式. 模块实例化端口连接方法: A.顺序端口连接:需严格按照模块定义时的顺序 B.明明端口连接:对端口信号顺序不做要求 Ex-1 ...