forked from TheAlgorithms/Java
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]>
- Loading branch information
1 parent
c54b8cd
commit 94621fb
Showing
5 changed files
with
129 additions
and
46 deletions.
There are no files selected for viewing
33 changes: 0 additions & 33 deletions
33
src/main/java/com/thealgorithms/datastructures/disjointsets/DisjointSets.java
This file was deleted.
Oops, something went wrong.
13 changes: 0 additions & 13 deletions
13
src/main/java/com/thealgorithms/datastructures/disjointsets/Node.java
This file was deleted.
Oops, something went wrong.
53 changes: 53 additions & 0 deletions
53
src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.thealgorithms.datastructures.disjointsetunion; | ||
|
||
/** | ||
* Disjoint Set Union or DSU is useful for solving problems related to connected components, | ||
* cycle detection in graphs, and maintaining relationships in disjoint sets of data. | ||
* It is commonly employed in graph algorithms and problems. | ||
* | ||
* @see <a href="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">Disjoint Set Union</a> | ||
*/ | ||
public class DisjointSetUnion<T> { | ||
|
||
/** | ||
* Creates a new node of DSU with parent initialised as same node | ||
*/ | ||
public Node<T> makeSet(final T x) { | ||
return new Node<T>(x); | ||
} | ||
|
||
/** | ||
* Finds and returns the representative (root) element of the set to which a given element belongs. | ||
* This operation uses path compression to optimize future findSet operations. | ||
*/ | ||
public Node<T> findSet(Node<T> node) { | ||
while (node != node.parent) { | ||
node = node.parent; | ||
} | ||
return node; | ||
} | ||
|
||
/** | ||
* Unions two sets by merging their representative elements. The merge is performed based on the rank of each set | ||
* to ensure efficient merging and path compression to optimize future findSet operations. | ||
*/ | ||
public void unionSets(final Node<T> x, final Node<T> y) { | ||
Node<T> nx = findSet(x); | ||
Node<T> ny = findSet(y); | ||
|
||
if (nx == ny) { | ||
return; // Both elements already belong to the same set. | ||
} | ||
// Merging happens based on rank of node, this is done to avoid long chaining of nodes and reduce time | ||
// to find root of the component. Idea is to attach small components in big, instead of other way around. | ||
if (nx.rank > ny.rank) { | ||
ny.parent = nx; | ||
} else if (ny.rank > nx.rank) { | ||
nx.parent = ny; | ||
} else { | ||
// Both sets have the same rank; choose one as the parent and increment the rank. | ||
ny.parent = nx; | ||
nx.rank++; | ||
} | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.thealgorithms.datastructures.disjointsetunion; | ||
|
||
public class Node<T> { | ||
|
||
/** | ||
* The rank of the node, used for optimizing union operations. | ||
*/ | ||
public int rank; | ||
|
||
/** | ||
* Reference to the parent node in the set. | ||
* Initially, a node is its own parent (represents a singleton set). | ||
*/ | ||
public Node<T> parent; | ||
|
||
/** | ||
* The data element associated with the node. | ||
*/ | ||
public T data; | ||
|
||
public Node(final T data) { | ||
this.data = data; | ||
parent = this; // Initially, a node is its own parent. | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.thealgorithms.datastructures.disjointsetunion; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
|
||
public class DisjointSetUnionTest { | ||
|
||
@Test | ||
public void testMakeSet() { | ||
DisjointSetUnion<Integer> dsu = new DisjointSetUnion<>(); | ||
Node<Integer> node = dsu.makeSet(1); | ||
assertNotNull(node); | ||
Assertions.assertEquals(node, node.parent); | ||
} | ||
|
||
@Test | ||
public void testUnionFindSet() { | ||
DisjointSetUnion<Integer> dsu = new DisjointSetUnion<>(); | ||
Node<Integer> node1 = dsu.makeSet(1); | ||
Node<Integer> node2 = dsu.makeSet(2); | ||
Node<Integer> node3 = dsu.makeSet(3); | ||
Node<Integer> node4 = dsu.makeSet(4); | ||
|
||
dsu.unionSets(node1, node2); | ||
dsu.unionSets(node3, node2); | ||
dsu.unionSets(node3, node4); | ||
dsu.unionSets(node1, node3); | ||
|
||
Node<Integer> root1 = dsu.findSet(node1); | ||
Node<Integer> root2 = dsu.findSet(node2); | ||
Node<Integer> root3 = dsu.findSet(node3); | ||
Node<Integer> root4 = dsu.findSet(node4); | ||
|
||
Assertions.assertEquals(node1, node1.parent); | ||
Assertions.assertEquals(node1, node2.parent); | ||
Assertions.assertEquals(node1, node3.parent); | ||
Assertions.assertEquals(node1, node4.parent); | ||
|
||
Assertions.assertEquals(node1, root1); | ||
Assertions.assertEquals(node1, root2); | ||
Assertions.assertEquals(node1, root3); | ||
Assertions.assertEquals(node1, root4); | ||
|
||
Assertions.assertEquals(1, node1.rank); | ||
Assertions.assertEquals(0, node2.rank); | ||
Assertions.assertEquals(0, node3.rank); | ||
Assertions.assertEquals(0, node4.rank); | ||
} | ||
} |