文章目录
1. 并查集1.1 并查集的概念1.2 并查集的实现思路1.3 代码
1. 并查集
1.1 并查集的概念
并查集也是一种数据结构,主要有两个操作,集合的合并,判断两个元素是否属于同一个集合,是一种逻辑结构。
1.2 并查集的实现思路
并查集的底层实现有多重方式,可以使用数组、List、树等等,选择的依据是哪种实现方式可以让操作的复杂度小。可以使用一种特殊的树来实现并查集如图,每一个结点都有一个父结点,最后一个结点的父节点指向自己,也是这个集合的代表结点,判断两个元素是否属于同一个集合,就是判断这两个元素所在集合的代表结点是否相等,合并两个集合,让结点数少的集合,挂载结点数多的代表结点的下面。 具体实现时,可以使用Map,使操作更简单。
1.3 代码
public class Code_09_UnionFind {
public static class Node{
}
public static class DisjointSets{
public Map
<Node, Node> fatherMap
;
public Map
<Node, Integer> sizeMap
;
public DisjointSets(List
<Node> list
){
fatherMap
= new HashMap<>();
sizeMap
= new HashMap<>();
makeSets(list
);
}
public void makeSets(List
<Node> list
){
fatherMap
.clear();
sizeMap
.clear();
for(Node node
: list
){
fatherMap
.put(node
, node
);
sizeMap
.put(node
, 1);
}
}
public Node
findFather(Node node
){
Node father
= fatherMap
.get(node
);
if(father
!= node
){
father
= findFather(father
);
}
fatherMap
.put(node
, father
);
return father
;
}
public boolean isSameSet(Node node1
, Node node2
){
return findFather(node1
) == findFather(node2
);
}
public void union(Node a
, Node b
){
if(a
== null
|| b
== null
) return;
Node aFather
= findFather(a
);
Node bFather
= findFather(b
);
if(aFather
!= bFather
){
int aFatherSize
= sizeMap
.get(aFather
);
int bFatherSize
= sizeMap
.get(bFather
);
if( aFatherSize
<= bFatherSize
){
fatherMap
.put(aFather
, bFather
);
sizeMap
.put(bFather
, aFatherSize
+ bFatherSize
);
}else{
fatherMap
.put(bFather
, aFather
);
sizeMap
.put(aFather
, aFatherSize
+ bFatherSize
);
}
}
}
}
}
时间复杂度:假设有n个元素,如果查询的次数(查找代表结点)加上合并的次数的数量级达到或者超过了O(n),那么,单次查询或者单次合并,平均复杂度为O(1)。证明过程很复杂,略。
如有不足之处,欢迎指正,谢谢!