数据结构——二十二、并查集(王道408)
文章目录
- 前言
- 一.逻辑结构——“集合”
- 1.全集
- 2.子集与森林
- 二.用互不相交的树,表示多个“集合”
- 1.查操作
- 2.并操作
- 三.代码实现并查集
- 1.存储结构——双亲表示法
- 1.定义
- 2.代码
- 3.图例
- 2.初始化
- 3.查操作
- 1.定义
- 2.代码
- 3.时间复杂度
- 4.并操作
- 1.定义
- 2.代码
- 3.时间复杂度
- 四.使用Union操作优化并查集
- 1.优化思路
- 2.代码展示
- 3.优化后影响
- 五.知识回顾与重要考点
- 结语
前言
本文介绍了并查集(Disjoint Set)的逻辑结构、存储实现和优化方法。主要内容包括:1)用互不相交的树表示集合,通过查操作(Find)和并操作(Union)实现集合操作;2)使用双亲表示法存储结构,给出初始化、查、并的代码实现;3)提出优化方案,通过小树合并到大树的方式控制树高,将查操作的时间复杂度从O(n)优化到O(log₂n)。并查集是一种高效处理不相交集合的数据结构,适用于需要频繁查询和合并集合的场景。文章还总结了并查集的重要考点和知识点框架。
代码在文章开头,有需要自取🧐
一.逻辑结构——“集合”
1.全集
2.子集与森林
-
将各个元素划分为若干个互不相交的子集
-
森林。森林是m(m≥0)棵互不相交的树的集合
-
同一子集中的各个元素,组织成一棵树用于表示各个子集之间互不相交的关系
二.用互不相交的树,表示多个“集合”
1.查操作
如何“查”到一个元素到底属于哪一个集合?
答:从指定元素出发,一直寻找它的父结点,直至找到根节点,根节点代表了其属于哪一棵树
如何判断两个元素是否属于同一个集合?
答:分别查到两个元素的根,判断根节点是否相同即可
2.并操作
如何把两个集合“并”为一个集合?
答:让一棵树成为另一棵树的子树即可
注:并查集(Disjoint Set)是逻辑结构——集合的一种具体实现,只进行“并”和“查”两种基本操作
三.代码实现并查集
1.存储结构——双亲表示法
1.定义
- 双亲表示法:每个结点中保存指向双亲的“指针”
2.代码
#define SIZE 13
int UFSets[SIZE]; //集合元素数组
3.图例
2.初始化
初始状态:所有的元素都是一个一个独立的结点
//初始化并查集
void Initial(int S[]){for(int i=0; i<SIZE; i++)S[i]=-1;
}
3.查操作
1.定义
- Find–“查”操作:确定一个指定元素所属集合
2.代码
//Find“查”操作,找x所属集合(返回x所属根结点)
//x表示这个元素的数组下标
int Find(int S[], int x){while(S[x]>=0)//循环寻找x的根x=S[x];return x; //根的S[]小于0
}
3.时间复杂度
- 若结点数为n,Find最坏时间复杂度为O(n)
4.并操作
1.定义
- Union–“并”操作:将两个不相交的集合合并为一个
2.代码
}
//Union“并”操作,将两个集合合并为一个
//Root1和Root2是要合并的两个集合的根结点
void Union(int S[], int Root1, int Root2){//要求Root1与Root2是不同的集合if(Root1==Root2) return;//将根Root2连接到另一根Root1下面S[Root2]=Root1;
}
3.时间复杂度
- 时间复杂度:O(1)
四.使用Union操作优化并查集
可以看出查这个操作的最坏的时间开销直接和树的高度的相关,如果我们想要优化这个并查集的效率的话,那我们能否在构造这个树的时候让这棵树别长得太高
1.优化思路
-
在每次Union操作构建树的时候,尽可能让树不长高
①用根节点的绝对值表示树的结点总数
②Union操作,让小树合并到大树 -
例子
- A这棵树有6个结点,因此存为-6
- C这棵树有2个结点,因此存为-2
- C这棵树有5个结点,因此存为-5
2.代码展示
//Union“并”操作,小树合并到大树
void Union(int S[], int Root1, int Root2){if(Root1==Root2) return;if(S[Root2]>S[Root1]){//Root2结点数更少S[Root1] += S[Root2]; //累加结点总数S[Root2]=Root1; //小树合并到大树}else{S[Root2] += S[Root1]; //累加结点总数S[Root1]=Root2; //小树合并到大树}
}
3.优化后影响
- 该方法构造的树高不超过⌊log2n⌋+1\lfloor log₂n\rfloor+1⌊log2n⌋+1
- Union操作优化后,Find操作最坏时间复杂度:O(log₂n)
五.知识回顾与重要考点
结语
二更😉
想要查看更多章节?请点击一、数据结构专栏导航页