package hjelpeklasser;
import java.util.*;
public class UnionFinn<T>
{
  private static final class Node
  {
    private Node forelder = null;
    private int antall = 1;
  }
  Map<T, Node> noder = new HashMap<>();
  
  private static Node finnRot(Node p)  
  {
    Node rotP = p;  
    while (rotP.forelder != null) rotP = rotP.forelder;  
    if (p != rotP) p.forelder = rotP;  
    return rotP;
  }
  private Node node(T e)
  {
    if (e == null) throw new NullPointerException("Ikke null som element!");
    Node p = noder.get(e);
    if (p == null)           
    {
      p = new Node();        
      noder.put(e, p);       
    }
    return p;
  }
  
  public int finnMengde(T e)
  {
    Node p = noder.get(e);
    return p == null ? 0 : finnRot(p).antall;
  }
  public boolean nyMengde(T e)
  {
    if (e == null) throw new NullPointerException("Ikke null som element!");
    if (noder.get(e) != null) return false;   
    else
    {
      noder.put(e, new Node());               
      return true;
    }
  }
  public int union(T e1, T e2)
  {
    Node rot1 = finnRot(node(e1));
    Node rot2 = finnRot(node(e2));
    if (rot1 == rot2) return 0;  
    if (rot1.antall < rot2.antall)  
    {
      rot1.forelder = rot2;
      rot2.antall += rot1.antall;
      return rot2.antall;
    }
    else 
    {
      rot2.forelder = rot1;
      rot1.antall += rot2.antall;
      return rot1.antall;
    }
  }
  public String mengde(T e)
  {
    Node p = noder.get(e);
    if (p == null) throw new NoSuchElementException("Ukjent element " + e + "!");
    StringJoiner s = new StringJoiner(", ", "{", "}");
    Node rot = finnRot(p);
    for (T ee : noder.keySet())
    {
      if (finnRot(noder.get(ee)) == rot) s.add(ee.toString());
    }
    return s.toString();
  }
}