### A data structure maintaining disjoint sets

parent c55fd312

* This data structure is used to maintain disjoint sets. It supports limited * number of operations, but they are all executed in constant amortized time. * The supported operations are: *

*
*
• Adding a new set containing a single element
• *
• Determining if two elements belong to the same set
• *
• Union of the sets containing two elements
• *
* *

* The space taken by this structure is O(n), where n is the number of elements. *

* * @param * the type of the elements */ public class DisjointSets { /** * Disjoint sets are represented as a forest. This class presents the tree * node associated to each element. */ protected static class Node { Node parent; int rank; protected Node() { parent = this; rank = 0; } protected Node root() { if (this != parent) parent = parent.root(); return parent; } protected void join(Node node) { Node x = root(); Node y = node.root(); if (x == y) return; if (x.rank > y.rank) y.parent = x; else { x.parent = y; if (x.rank == y.rank) y.rank++; } } } /** * Correspondence between elements and nodes. */ protected Map map; /** * Creates a new instance containing no sets and no elements */ public DisjointSets() { map = new HashMap(); } /** * Creates a new instance containing no sets and no elements. If the total * number of elements to add is known in advance, this constructor is more * efficient than the default. * * @param initialCapacity * Initial capacity (in number of elements) of the structure. The * structure grows dynamically and new elements can be added even * if this capacity is exceeded. */ public DisjointSets(int initialCapacity) { map = new HashMap(4 * initialCapacity / 3 + 1); } /** * Adds a new set containing only {@code e} to the structure. If {@code e} already belongs * to some of the disjoint sets, nothing happens. * * @param e The element to add as a singleton * @return True if the new set is added and false if {@code e} already belongs to some set. */ public boolean add(E e) { Node x = map.get(e); if (x != null) return false; map.put(e, new Node()); return true; } /** * Checks if two elements belong to the same set. * @param e1 An element * @param e2 An element * @return True if and only if belong to the same set. * Note that if {@code e1} or {@code e2} do not belong to any set, false is returned. */ public boolean inSameSet(Object e1, Object e2) { Node x1 = map.get(e1); if (x1 == null) return false; Node x2 = map.get(e2); if (x2 == null) return false; return x1.root() == x2.root(); } /** * Union of the set containing {@code e1} and the set containing {@code e2}. After this operation {@code inSameSet(e1, e2)} will return true. * If {@code e1} or {@code e2} do not belong to any set or if they already belong to the same set, nothing happens. * @param e1 An element * @param e2 An element */ public void union(Object e1, Object e2) { Node x1 = map.get(e1); if (x1 == null) return; Node x2 = map.get(e2); if (x2 == null) return; x1.join(x2); } /** * Checks if an element belongs to some of the disjoint sets. * @param e An element * @return True if {@code e} belongs to some set. */ public boolean contains(Object e) { return map.get(e) != null; } /** * Reinitializes the structure. After this operation the structure contains no sets. */ public void clear() { for (Node node : map.values()) node.parent = null; map.clear(); } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!