并查集概述

目录

并查集概述

并查集一般要处理的问题

并查集的实现方法

最后(求看)


并查集概述

并查集是一种树型的数据结构,由于处理一些不相交集合的合并及查询问题。

并查集思想是用一个数组表示了整片森林,树的根节点唯一是一个集合的标识,我们只要找到了某个元素的树确定它在哪个集合里。

如图(主干就是根节点,枝干就是子节点):


并查集一般要处理的问题

  1. 合并:将若干点合并到一个或多个集合(构成的一颗树或多棵树),将多个集合合并(多棵树合并为一棵树);
  2. 查询:询问某2个点是否在同一个集合中;
  3. 其他:计算共有多少个集合(多少棵树)。

并查集的实现方法

(1)举例说明

假设有如下8个点:1 2 3 4 5 6 7 8,假设如下两两的结点在一个集合中,通过并查集构建过程的模拟来看最终有几个集合,并理解并查集的构建过程和查询过程。

两两在一个集合中的节点有:

1 3

1 2

5 4

2 4

6 8

8 7

如图:

(2)数据结构的实现

实际操作时,我们会使用一个点来代表整个集合,就是一个元素的根节点(可以理解为父亲)。

实现方法:

我们要建立一个数组 f[ ] 表示一个并查集,f[i] 表示 i 的父节点。

  1. 初始化:一开始每一个节点都是一个集合,因此自己的父节点就是自己 f[i]=i (毕竟之后是要合并的)。
  2. 查询:每一个节点不断地寻找自己的父节点,若此时自己的父节点就是自己,那么该点为集合的根节点,随后返回该点。
  3. 合并:合并两个集合只需要合并两个集合的根节点,即f[RootA]=RootB,其中RootA,RootB是两个元素的根节点。
  4. 路径压缩:大多数情况下,在查询过程中只关心根节点是什么,并不关心这棵树的形态。因此我们可以再查询操作的时候将访问过的每个点都指向根节点,这样的方法叫做路径压缩。

如图:

初始化模板:

for(int i=1;i<=n;i++) f[i]=i;//只是模板,切勿直接运行

基本查询模板:求x的根:

int find(int x){
    return f[x]==x?x:find(f[x]);//三位运算符(不会的话,切勿使用!!!)
    /*
    if(f[x]==x) return x;
    else return f[x]=find(f[x]);
    (上面是三位运算符的正常版(新手用))
    */
}

路径压缩查询模板:

return f[x]==x?x:find(f[x]);//三位运算符(不会的话,切勿使用!!!)
/*
if(f[x]==x) return x;
else return f[x]=find(f[x]);
(上面是三位运算符的正常版(新手用))
*/

合并模板:先判断x和y是否在同一个集合:

void merge(int x,int y){
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy) f[fx]=fy;
}

注意:合并与查询是亲兄弟,要一起用呦!!! 


最后(求看)

最后,现在我们就学完了并查集,并查集其实并不难,难的是要写太多字了!!!以上是作者本人自己总结。我还要说的是:看官们在学习后要趁热打铁做一份笔记呦(有利于加深理解)。

最后的最后:

我收到的评论有点少,希望看官们有时间能多评论指教一下我,谢谢了!!!

!!!

!!!

!!!

### 并查集算法概述 并查集是一种树型的数据结构,主要用于处理一些不相交集合(disjoint sets)的合并及查询问题。这种数据结构常被用来管理动态连通性,在初始状态下,每个元素各自构成一个独立的集合;随着程序运行,某些操作会促使不同集合之间的合并。 #### 数据结构特点 在实际应用中,并查集通常通过森林的形式展现出来——即一组互不关联的小树群。每棵树代表了一个独特的集合,而树中的节点则对应着各个成员个体[^1]。 #### 主要功能与操作 对于并查集而言,其核心在于支持三项基础动作: - **查找 (Find)**:确定某个特定项所属的具体分组; - **合并 (Union)**:把两个指定子群体合成为一个更大的整体; - **连通性检测 (Is_Connected)**:验证任意两者间是否存在直接或间接的关系路径[^2]。 #### 实现细节 为了高效地完成上述任务,并查集内部采用了数组作为底层存储介质。具体来说,每一个位置上的数值指示了该索引所指代对象的父亲节点身份。当遇到根部时,则指向自己形成闭环标志位。此外,还引入了一种叫做“秩”的概念辅助优化性能表现,它反映了当前分支的高度信息以便更好地控制平衡度[^3]。 ```python class UnionFind: def __init__(self, size): self.parent = list(range(size)) self.rank = [0] * size def find(self, p): if self.parent[p] != p: self.parent[p] = self.find(self.parent[p]) # 路径压缩 return self.parent[p] def union(self, p, q): rootP = self.find(p) rootQ = self.find(q) if rootP != rootQ: if self.rank[rootP] > self.rank[rootQ]: self.parent[rootQ] = rootP elif self.rank[rootP] < self.rank[rootQ]: self.parent[rootP] = rootQ else: self.parent[rootQ] = rootP self.rank[rootP] += 1 def is_connected(self, p, q): return self.find(p) == self.find(q) ``` 这段Python代码展示了如何构建一个简单的并查集类`UnionFind`,其中包含了初始化函数、查找函数(find),带有路径压缩机制以加速后续访问速度;还有联合函数(union),利用按秩合并策略减少树高从而提升效率;最后是一个判断两元素是否同属一簇的方法(is_connected)。 #### 应用场景举例 并查集广泛应用于计算机科学领域内涉及图论的各种场合下,比如最小生成树(MST)计算(Kruskal's Algorithm)、社交网络分析里寻找社区结构等问题求解过程之中都离不开这一强大工具的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值