一、并查集概念

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

    • 查找(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. SQL面试50题------(初始化工作、建立表格)

    文章目录 1.建表 1.1 学生表和插入数据 1.2 教师表和数据 1.3 课程表和数据 1.4 成绩表和数据 2.数据库数据 2.1 学生表 2.2 教师表 2.3 课程表 2.4 得分表 1.建表 ...

  2. 常用排序算法(C语言)

    1.冒泡排序 void BubbleSort(int a[],int len) {int tmp; for (int i=0; i<n-1; i++) { int flag = FALSE; f ...

  3. SystemParametersInfo函数说明

    SystemParametersinfo 返回值:如果函数调用成功,返回值非零:如果函数调用失败,那么返回值为零.若想获取更多错误信息,请调用GetLastError函数. SystemParamet ...

  4. 一个实用的 vite + vue3 组件库脚手架工具,提升开发效率

    无论是 vue2 全家桶还是 vue3 + vite + TypeScript,组件库的使用几乎大家都会,但自己开发一个独立组件库就不是每个人都掌握的,因为搭建组件库的基础开发环境,就会让很多同学望而 ...

  5. Spring Boot:自定义 Whitelabel 错误页面

    一.概述在本文中,我们将研究如何禁用和自定义 Spring Boot 应用程序的默认错误页面,因为正确的错误处理描述了专业性和质量工作. 2.禁用白标错误页面 首先,让我们看看如何通过将server. ...

  6. [AGC057D] Sum Avoidance

    Link 本篇题解大部分内容来自这篇文章 首先题意翻译: 给定一个正整数 \(S\) ,称一个正整数集合 \(A\) 是好的,当且仅当它满足以下条件: \(A\) 中元素在 \((0,S)\) 之间 ...

  7. springcloud组件梳理之hystrix

    在微服务架构体系中,各服务中间的相互调用是常态,没有哪个服务能保证自身百分百不会出问题,然后再加上网络的波动以及环境等问题,服务间调用的稳定性无法保证,这时候就需要一个有容错能力的组件来介入,当调用出 ...

  8. Mysql InnoDB多版本并发控制MVCC

    参考书籍<mysql是怎样运行的> 系列文章目录和关于我 一丶为什么需要事务隔离级别 mysql是一个客户端/服务断软件,对于同一个服务器来说,可以有多个客户端进行连接,每一个客户端进行连 ...

  9. tomcat报Address localhost:1099 is already in use

    idea运行tomcat报Address localhost:1099 is already in use 解决方案: 电脑桌面->ctrl+shift+esc 打开任务管理器,选择详细信息,找 ...

  10. Typora基本使用

    Typora主要功能介绍 1.语言环境 文件>>>偏好设置>>>系统语言 2.创建另一个编辑页面 ctrl+N 几乎所有软件的新建页面的快捷键都是它 3.保存文件 ...