package com.gxu.dawnlab_algorithm5;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
/**
* 并查集结构
* @author junbin
*
* 2019年7月7日
*/
public class UnionFind {
public static class Element<V> {
public V value;
public Element(V value){
this.value = value;
}
}
public static class UnionFindSet<V> {
public HashMap<V, Element<V>> elementMap;
public HashMap<Element<V>, Element<V>> fatherMap;
public HashMap<Element<V>, Integer> rankMap;
public UnionFindSet(List<V> list) {
elementMap = new HashMap<V, Element<V>>();
fatherMap = new HashMap<Element<V>, Element<V>>();
rankMap = new HashMap<Element<V>, Integer>();
for(V value : list){
Element<V> element = new Element<V>(value);
elementMap.put(value, element);
fatherMap.put(element, element);
rankMap.put(element, 1);
}
}
private Element<V> findHead(Element<V> element) {
Stack<Element<V>> path = new Stack<Element<V>>();
while(element != fatherMap.get(element)){
path.push(element);
element = fatherMap.get(element);
}
while(!path.isEmpty()){
fatherMap.put(path.pop(), element);
}
return element;
}
public boolean isSameSet(V a, V b) {
return findHead(elementMap.get(a)) == findHead(elementMap.get(b));
}
public void union(V a, V b) {
if (elementMap.containsKey(a) && elementMap.containsKey(b)) {
Element<V> aF = findHead(elementMap.get(a));
Element<V> bF = findHead(elementMap.get(b));
if(aF != bF){
Element<V> big = rankMap.get(aF) >= rankMap.get(bF) ? aF : bF;
Element<V> small = big == aF ? bF : aF;
fatherMap.put(small, big);
rankMap.put(big, rankMap.get(aF) + rankMap.get(bF));
rankMap.remove(small);
}
}
}
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
list.add("g");
UnionFindSet<String> union = new UnionFindSet<String>(list);
System.out.println(union.isSameSet("a", "b"));
union.union("a", "b");
}
}
}
「プログラマーコード面接ガイド」P476の詳細を参照してください。