目录
一、并查集是什么
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的并、查)。
并查集跟树有些类似,只不过她跟树是相反的。
树结构:
在树这个数据结构里面,每个节点会记录它的子节点。
在并查集里,每个节点会记录它的父节点【1】。
并查集的精髓在于,两块集合(区域)有没有相交,以及要不要联通两块区域(集合)。
参考树的结构,把元素挂到父节点下,若两个元素的父节点相同,则是同一块区域,两个元素的父
节点不相同,则不是同一块区域。
以上图为例,1和2是同一片区域,3和4是同一片区域,5自己是一片区域,那么以上总共有三个区
域。
并查集结构(HashMap为例):
比如说,我们可以用并查集来判断一个森林中有几棵树、某个节点是否属于某棵树等。
说简单一点,并查集就是将一些数据进行分类,这样一些数据为一组,例外一些数据为另一组。
如何判断其中两个数据,在不在一个组?
我们就会去找每个组的代表,看这两个数据的代表是不是同一个?
如果是,那就是在一个组;如果不是,那就不在一个组。
所以并查集的大致框架就是下面这样:
//并查集大致框架---代码中的数据(Node),可以是其他,比如二叉树节点、图的边、节点等等 抽象的数据
public class UnionSet {
private HashMap<Node, Node> fatherMap; //key表示当前这个数据,value表示这个数据的代表(父亲)是谁
private HashMap<Node, Integer> sizeMap; //表示当前这个组(集合)的大小
public UnionSet() { //构造方法
fatherMap = new HashMap<>();
sizeMap = new HashMap<>();
}
public void makeSet(List<Node> list) { //生成初始化状态的并查集,刚开始每个数据都是独立的
}
public boolean isSameSet(Node node1, Node node2) { //判断当前这两个数据,是不是一个组的?
}
private Node findFather(Node node) { //查找这个数据,它那个组的代表(父亲)是谁?
}
public void union(Node node1, Node node2) { //将这两个数据,放到一个组
}
}
上面就是大致的框架,就是几个方法:初始化并查集、判断是不是一个组、查找代表、合并到一个
组。
四个方法,就是并查集。
简不简单?
并查集在判断两个数据,是否在一个组时,时间复杂度能做到O(1),所以这种数据结构还是非常有
用的。
得出结论:
1. 并查集的整体构成分为三部分:
- 并,代表合并
- 查,代表查找
- 集,代表一个集合,这个集合中,大家的父节点都指向一个地方,即每个节点会记录它的父节点
2. 并查集可以高效地进行如下操作:
- 查询元素p和元素q是否属于同一组
- 合并元素p和元素q所在的组
3. 并查集要求比较简单:
- 每个元素都唯一的对应一个结点;
- 每一组数据中的多个元素都在同一颗树中;
- 一个组中的数据对应的树和另外一个组中的数据对应的树之间没有任何联系;
- 元素在树中并没有子父级关系的硬性要求;