package edu.stanford.nlp.util; import java.util.*; /** * Disjoint forest with path compression and union-by-rank. The set * is unmodifiable except by unions. * * @author Dan Klein * @version 4/17/01 */ public class FastDisjointSet<T> implements DisjointSet<T> { static class Element<TT> { Element<TT> parent; int rank; TT object; Element(TT o) { object = o; rank = 0; parent = this; } } private Map<T, Element<T>> objectToElement; private static <TTT> void linkElements(Element<TTT> e, Element<TTT> f) { if (e.rank > f.rank) { f.parent = e; } else { e.parent = f; if (e.rank == f.rank) { f.rank++; } } } private static <TTT> Element<TTT> findElement(Element<TTT> e) { if (e.parent == e) { return e; } Element<TTT> rep = findElement(e.parent); e.parent = rep; return rep; } @Override public T find(T o) { Element<T> e = objectToElement.get(o); if (e == null) { return null; } Element<T> element = findElement(e); return element.object; } @Override public void union(T a, T b) { Element<T> e = objectToElement.get(a); Element<T> f = objectToElement.get(b); if (e == null || f == null) { return; } if (e == f) { return; } linkElements(findElement(e), findElement(f)); } public FastDisjointSet(Set<? extends T> objectSet) { objectToElement = Generics.newHashMap(); for (T o : objectSet) { // create an element Element<T> e = new Element<>(o); objectToElement.put(o, e); } } }