|
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); |
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