1. 并查集的介绍
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的并、查)。
在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union-find set)。
比如:某公司今年校招全国总共招生10人,西安招4人,成都招3人,武汉招3人,10个人来自不同的学校,起先互不相识,每个学生都是一个独立的小团体,我们给这10个人进行编号。
每个地方的学生自发组织成小分队一起上路,于是:西安的4名同学(编号为0,6,7,8)组成了一个团体,成都的三名同学(编号为1,4,9)组成了一个团体,武汉的3名同学(编号为2,3,5)组成了一个团体。假设由编号最小的同学担任队长。
有了这个结构之后,我们很容易就能判断出来某两位同学是否属于同一个团体,并且合并两个集合也非常方便,这就是并查集的价值所在。
2. 并查集的原理
在实际中我们可以通过一个数组来实现并查集,还是上面那个例子。我们定义一个数组,这个数组的下标就是每个成员的编号,数组中的值有两层意思:
1.对队长(根节点)来说,数组中保存这个集合中所有元素的个数 * -1。
2.对成员(除了根节点的其他结点)来说,数组中保存的是他的父节点的下标。
所以数组中值 < 0 的都是根节点,根节点得绝对值是这个集合的元素个数。
最初一开始所有同学都是一个独立的团体,所以先初始化为 -1。
后续相同城市的同学组成了一个团体。
物理结构图如下:
逻辑结构图如下:
并查集可以用来解决哪些问题?
1.查找元素属于哪个集合
由于数组中保存的是他父节点的下标,所以我们可以根据这个特点,一路向上查找,直到找到一个是值为负数的结点即可
2.查找两个元素是否属于同一集合
沿着数组表示的树形关系往上一直找到树的根,如果根相同表明在同一个集合,否则不在
3.将两个集合合并成一个集合
需要做以下两步
- 将两个集合中的元素合并
- 将一个集合名称改成另一个集合的名称
比如上面的例子,{0,6,7,8}集合和{1,4,9}进行合并。
注意观察数组的变化,1号由原来的-3变成0&#x