|
1 | 1 | package com.thealgorithms.datastructures.disjointsetunion;
|
2 | 2 |
|
3 | 3 | /**
|
4 |
| - * Disjoint Set Union or DSU is useful for solving problems related to connected components, |
5 |
| - * cycle detection in graphs, and maintaining relationships in disjoint sets of data. |
6 |
| - * It is commonly employed in graph algorithms and problems. |
| 4 | + * Disjoint Set Union (DSU), also known as Union-Find, is a data structure that tracks a set of elements |
| 5 | + * partitioned into disjoint (non-overlapping) subsets. It supports two primary operations efficiently: |
7 | 6 | *
|
8 |
| - * @see <a href="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">Disjoint Set Union</a> |
| 7 | + * <ul> |
| 8 | + * <li>Find: Determine which subset a particular element belongs to.</li> |
| 9 | + * <li>Union: Merge two subsets into a single subset.</li> |
| 10 | + * </ul> |
| 11 | + * |
| 12 | + * @see <a href="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">Disjoint Set Union (Wikipedia)</a> |
9 | 13 | */
|
10 | 14 | public class DisjointSetUnion<T> {
|
11 | 15 |
|
12 | 16 | /**
|
13 |
| - * Creates a new node of DSU with parent initialised as same node |
| 17 | + * Creates a new disjoint set containing the single specified element. |
| 18 | + * |
| 19 | + * @param value the element to be placed in a new singleton set |
| 20 | + * @return a node representing the new set |
14 | 21 | */
|
15 |
| - public Node<T> makeSet(final T x) { |
16 |
| - return new Node<T>(x); |
| 22 | + public Node<T> makeSet(final T value) { |
| 23 | + return new Node<>(value); |
17 | 24 | }
|
18 | 25 |
|
19 | 26 | /**
|
20 |
| - * Finds and returns the representative (root) element of the set to which a given element belongs. |
21 |
| - * This operation uses path compression to optimize future findSet operations. |
| 27 | + * Finds and returns the representative (root) of the set containing the given node. |
| 28 | + * This method applies path compression to flatten the tree structure for future efficiency. |
| 29 | + * |
| 30 | + * @param node the node whose set representative is to be found |
| 31 | + * @return the representative (root) node of the set |
22 | 32 | */
|
23 | 33 | public Node<T> findSet(Node<T> node) {
|
24 |
| - while (node != node.parent) { |
25 |
| - node = node.parent; |
| 34 | + if (node != node.parent) { |
| 35 | + node.parent = findSet(node.parent); // Path compression |
26 | 36 | }
|
27 |
| - return node; |
| 37 | + return node.parent; |
28 | 38 | }
|
29 | 39 |
|
30 | 40 | /**
|
31 |
| - * Unions two sets by merging their representative elements. The merge is performed based on the rank of each set |
32 |
| - * to ensure efficient merging and path compression to optimize future findSet operations. |
| 41 | + * Merges the sets containing the two given nodes. Union by rank is used to attach the smaller tree under the larger one. |
| 42 | + * If both sets have the same rank, one becomes the parent and its rank is incremented. |
| 43 | + * |
| 44 | + * @param x a node in the first set |
| 45 | + * @param y a node in the second set |
33 | 46 | */
|
34 |
| - public void unionSets(final Node<T> x, final Node<T> y) { |
35 |
| - Node<T> nx = findSet(x); |
36 |
| - Node<T> ny = findSet(y); |
| 47 | + public void unionSets(Node<T> x, Node<T> y) { |
| 48 | + Node<T> rootX = findSet(x); |
| 49 | + Node<T> rootY = findSet(y); |
37 | 50 |
|
38 |
| - if (nx == ny) { |
39 |
| - return; // Both elements already belong to the same set. |
| 51 | + if (rootX == rootY) { |
| 52 | + return; // They are already in the same set |
40 | 53 | }
|
41 | 54 | // Merging happens based on rank of node, this is done to avoid long chaining of nodes and reduce time
|
42 | 55 | // to find root of the component. Idea is to attach small components in big, instead of other way around.
|
43 |
| - if (nx.rank > ny.rank) { |
44 |
| - ny.parent = nx; |
45 |
| - } else if (ny.rank > nx.rank) { |
46 |
| - nx.parent = ny; |
| 56 | + if (rootX.rank > rootY.rank) { |
| 57 | + rootY.parent = rootX; |
| 58 | + } else if (rootY.rank > rootX.rank) { |
| 59 | + rootX.parent = rootY; |
47 | 60 | } else {
|
48 |
| - // Both sets have the same rank; choose one as the parent and increment the rank. |
49 |
| - ny.parent = nx; |
50 |
| - nx.rank++; |
| 61 | + rootY.parent = rootX; |
| 62 | + rootX.rank++; |
51 | 63 | }
|
52 | 64 | }
|
53 | 65 | }
|
0 commit comments