并查集结构code

This commit is contained in:
Wen 2022-09-07 23:50:17 +08:00
parent 761f4e12a0
commit 8c6285f740
1 changed files with 85 additions and 0 deletions

View File

@ -0,0 +1,85 @@
package ds.picture;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
/**
* 并查集
* @author Wen
* @date 2022/9/7 23:27
*/
public class UnionFind {
//集合结构体
static class Node<T> {
T t;
public Node(T t) {
this.t = t;
}
}
static class UnionFindSet<V> {
//自身代表点指向集合
private HashMap<V, Node<V>> nodeHashMap;
//每个结构体上层指向存储
private HashMap<Node<V>, Node<V>> parentMap;
//代表结构体的总节点数
private HashMap<Node<V>, Integer> sizeMap;
public UnionFindSet(List<V> iterator) {
int size = iterator.size();
nodeHashMap = new HashMap<>(size);
parentMap = new HashMap<>(size);
sizeMap = new HashMap<>(size);
for (V v : iterator) {
Node<V> node = new Node<>(v);
nodeHashMap.put(v, node);
parentMap.put(node, node);
sizeMap.put(node, 1);
}
}
//找代表节点
public Node<V> findFather(Node<V> cur) {
Stack<Node<V>> stack = new Stack<>();
while (parentMap.get(cur) != cur) {
stack.push(cur);
cur = parentMap.get(cur);
}
//将从cur出发的链压平所经过的节点的代表节点都是cur的代表节点
while (!stack.isEmpty()) {
parentMap.put(stack.pop(), cur);
}
return cur;
}
//是否拥有同一个代表结点
public boolean isSameSet(V a, V b) {
if (nodeHashMap.get(a) == null || nodeHashMap.get(b) == null) {
return false;
}
return findFather(nodeHashMap.get(a)) == findFather(nodeHashMap.get(b));
}
//将小集合合并到大集合
public void union(V a, V b) {
if (nodeHashMap.get(a) == null || nodeHashMap.get(b) == null) {
return;
}
Node<V> aHead = findFather(nodeHashMap.get(a));
Node<V> bHead = findFather(nodeHashMap.get(b));
if (aHead != bHead) {
Node<V> bigHead = sizeMap.get(aHead) > sizeMap.get(bHead) ? aHead : bHead;
Node<V> smallHead = bigHead == aHead ? bHead : aHead;
parentMap.put(smallHead, bigHead);
sizeMap.put(bigHead, sizeMap.get(bigHead) + sizeMap.get(smallHead));
sizeMap.remove(smallHead);
}
}
}
}