Skip to content

Commit 94621fb

Browse files
Enhancing DisjointSetUnion data structure (TheAlgorithms#4366)
* Enhancing DisjointSetUnion data structure * Linter resolved * Linter resolved * Linter resolved * Linter resolved * Added next line * added next Line * Resolve review comments --------- Co-authored-by: Bama Charan Chhandogi <b.c.chhandogi@gmail.com>
1 parent c54b8cd commit 94621fb

File tree

5 files changed

+129
-46
lines changed

5 files changed

+129
-46
lines changed

src/main/java/com/thealgorithms/datastructures/disjointsets/DisjointSets.java

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/main/java/com/thealgorithms/datastructures/disjointsets/Node.java

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.thealgorithms.datastructures.disjointsetunion;
2+
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.
7+
*
8+
* @see <a href="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">Disjoint Set Union</a>
9+
*/
10+
public class DisjointSetUnion<T> {
11+
12+
/**
13+
* Creates a new node of DSU with parent initialised as same node
14+
*/
15+
public Node<T> makeSet(final T x) {
16+
return new Node<T>(x);
17+
}
18+
19+
/**
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.
22+
*/
23+
public Node<T> findSet(Node<T> node) {
24+
while (node != node.parent) {
25+
node = node.parent;
26+
}
27+
return node;
28+
}
29+
30+
/**
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.
33+
*/
34+
public void unionSets(final Node<T> x, final Node<T> y) {
35+
Node<T> nx = findSet(x);
36+
Node<T> ny = findSet(y);
37+
38+
if (nx == ny) {
39+
return; // Both elements already belong to the same set.
40+
}
41+
// Merging happens based on rank of node, this is done to avoid long chaining of nodes and reduce time
42+
// 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;
47+
} else {
48+
// Both sets have the same rank; choose one as the parent and increment the rank.
49+
ny.parent = nx;
50+
nx.rank++;
51+
}
52+
}
53+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.thealgorithms.datastructures.disjointsetunion;
2+
3+
public class Node<T> {
4+
5+
/**
6+
* The rank of the node, used for optimizing union operations.
7+
*/
8+
public int rank;
9+
10+
/**
11+
* Reference to the parent node in the set.
12+
* Initially, a node is its own parent (represents a singleton set).
13+
*/
14+
public Node<T> parent;
15+
16+
/**
17+
* The data element associated with the node.
18+
*/
19+
public T data;
20+
21+
public Node(final T data) {
22+
this.data = data;
23+
parent = this; // Initially, a node is its own parent.
24+
}
25+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.thealgorithms.datastructures.disjointsetunion;
2+
3+
import static org.junit.jupiter.api.Assertions.assertNotNull;
4+
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Test;
7+
8+
public class DisjointSetUnionTest {
9+
10+
@Test
11+
public void testMakeSet() {
12+
DisjointSetUnion<Integer> dsu = new DisjointSetUnion<>();
13+
Node<Integer> node = dsu.makeSet(1);
14+
assertNotNull(node);
15+
Assertions.assertEquals(node, node.parent);
16+
}
17+
18+
@Test
19+
public void testUnionFindSet() {
20+
DisjointSetUnion<Integer> dsu = new DisjointSetUnion<>();
21+
Node<Integer> node1 = dsu.makeSet(1);
22+
Node<Integer> node2 = dsu.makeSet(2);
23+
Node<Integer> node3 = dsu.makeSet(3);
24+
Node<Integer> node4 = dsu.makeSet(4);
25+
26+
dsu.unionSets(node1, node2);
27+
dsu.unionSets(node3, node2);
28+
dsu.unionSets(node3, node4);
29+
dsu.unionSets(node1, node3);
30+
31+
Node<Integer> root1 = dsu.findSet(node1);
32+
Node<Integer> root2 = dsu.findSet(node2);
33+
Node<Integer> root3 = dsu.findSet(node3);
34+
Node<Integer> root4 = dsu.findSet(node4);
35+
36+
Assertions.assertEquals(node1, node1.parent);
37+
Assertions.assertEquals(node1, node2.parent);
38+
Assertions.assertEquals(node1, node3.parent);
39+
Assertions.assertEquals(node1, node4.parent);
40+
41+
Assertions.assertEquals(node1, root1);
42+
Assertions.assertEquals(node1, root2);
43+
Assertions.assertEquals(node1, root3);
44+
Assertions.assertEquals(node1, root4);
45+
46+
Assertions.assertEquals(1, node1.rank);
47+
Assertions.assertEquals(0, node2.rank);
48+
Assertions.assertEquals(0, node3.rank);
49+
Assertions.assertEquals(0, node4.rank);
50+
}
51+
}

0 commit comments

Comments
 (0)