import java.util.HashMap;
import java.util.List;
import java.util.Stack;
public class UnionFind {
public static class Element<V> {
public V value;
public Element(V value) {
this.value = value;
}
}
public static class UnionFindSet<V> {
//元素的map,获取节点内部包裹内容
public HashMap<V, Element<V>> elementMap;
// key 某个元素 value 元素的父
public HashMap<Element<V>, Element<V>> fatherMap;
// key 某个集合的代表元素 value 该集合的元素个数
public HashMap<Element<V>, Integer> sizeMap;
public UnionFindSet(List<V> list) {
elementMap = new HashMap<>();
fatherMap = new HashMap<>();
sizeMap = new HashMap<>();
for (V value :
list) {
Element<V> element = new Element<>(value);
elementMap.put(value, element);
fatherMap.put(element, element); //刚开始自身成一个圈
sizeMap.put(element, 1);
}
}
寻找代表元素方法
//给定一个element 向上一直找 找到代表元素
private Element<V> findHead(Element<V> element) {
Stack<Element<V>> stack = new Stack<>();
while (element != fatherMap.get(element)) {
stack.push(element);
element = fatherMap.get(element);
}
//将整个数据结构扁平化 变成一个高为2 的 多叉树
while (!stack.isEmpty()) {
fatherMap.put(stack.pop(), element);
}
return element;
}
判断两个元素是不是一个集合
//查询两个元素是不是一个集合
public Boolean isSameSet(V a, V b) {
if (elementMap.containsKey(a) && elementMap.containsValue(b)) {
return findHead(elementMap.get(a)) == findHead(elementMap.get(b));
}
return false;
}
并查集合并方法
public void union(V a, V b) {
if (elementMap.containsKey(a) && elementMap.containsValue(b)) {
Element<V> afather = findHead(elementMap.get(a));
Element<V> bfather = findHead(elementMap.get(b));
if (afather != bfather) {
Element<V> big = sizeMap.get(afather) >= sizeMap.get(bfather) ? afather : bfather;
Element<V> small = big == afather ? bfather : afather;
fatherMap.put(small,big);
sizeMap.put(big,sizeMap.get(afather)+sizeMap.get(bfather));
}
}
}
}
}
并查集的基本定义import java.util.HashMap;import java.util.List;import java.util.Stack;public class UnionFind { public static class Element<V> { public V value; public Element(V value) { this.value = value; }