Skip to content

Commit a1eee93

Browse files
committed
added union find
1 parent 84c257f commit a1eee93

File tree

2 files changed

+92
-29
lines changed

2 files changed

+92
-29
lines changed

Algorithms/graph/unionFind.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Union-Find (Disjoint Set Union) implementation with path compression and union by rank
2+
3+
// Detect cycle in undirected graph using Union-Find
4+
// Algorithm steps:
5+
// 1. Initialize each element to be its own parent (self root) and rank 0.
6+
// 2. For each union operation, find the roots of the elements.
7+
// 3. If roots are different, union them by rank.
8+
// 4. If roots are the same, a cycle is detected.
9+
10+
// Time Complexity: O(α(N)) per operation, where α is the inverse Ackermann function
11+
// which grows very slowly, effectively constant for all practical N.
12+
// For interviews, we can consider it O(1) amortized time per operation.
13+
// Space Complexity: O(N) for storing parent and rank
14+
15+
// usage of Union-Find data structure:
16+
// 1. Cycle detection in undirected graphs
17+
// 2. Connected components in graphs
18+
// 3. Kruskal's algorithm for Minimum Spanning Tree
19+
// 4. Network connectivity problems
20+
21+
class UnionFind {
22+
constructor() {
23+
this.parent = new Map();
24+
this.rank = new Map();
25+
}
26+
27+
find(x) {
28+
// Step 1: Initialize new element if not seen before
29+
if (!this.parent.has(x)) {
30+
this.parent.set(x, x); // Element is its own parent (root)
31+
this.rank.set(x, 0); // Initial rank is 0
32+
}
33+
34+
// Step 2: Path compression optimization
35+
if (this.parent.get(x) !== x) {
36+
this.parent.set(x, this.find(this.parent.get(x))); // Recursive call
37+
}
38+
39+
// Step 3: Return the root
40+
return this.parent.get(x);
41+
}
42+
43+
union(x, y) {
44+
const rootX = this.find(x)
45+
const rootY = this.find(y)
46+
47+
if (rootX === rootY) {
48+
return false // Already in the same set
49+
}
50+
51+
// Union by rank
52+
// Case 1: rootX has higher rank
53+
if (this.rank.get(rootX) > this.rank.get(rootY)) {
54+
this.parent.set(rootY, rootX)
55+
// No rank change needed - rootX's rank stays the same
56+
}
57+
58+
// Case 2: rootY has higher rank
59+
else if (this.rank.get(rootX) < this.rank.get(rootY)) {
60+
this.parent.set(rootX, rootY)
61+
// No rank change needed - rootY's rank stays the same
62+
}
63+
64+
// Case 3: Both have equal rank
65+
else {
66+
this.parent.set(rootY, rootX) // rootX becomes the new root
67+
this.rank.set(rootX, this.rank.get(rootX) + 1) // Only rootX rank increases
68+
}
69+
return true
70+
}
71+
72+
connected(x, y) {
73+
return this.find(x) === this.find(y);
74+
}
75+
}
76+
77+
78+
// Example usage:
79+
const uf = new UnionFind();
80+
uf.union(1, 2);
81+
uf.union(2, 3);
82+
uf.union(4, 5);
83+
uf.union(5, 6);
84+
85+
console.log(uf.connected(1, 3)); // true
86+
console.log(uf.connected(1, 4)); // false
87+
uf.union(3, 4);
88+
console.log(uf.connected(1, 4)); // true
89+
90+
91+
// Questions for practice:
92+
// - Checking Existence of Edge Length Limited Paths

Data Structures/graph/unionFind.js

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

0 commit comments

Comments
 (0)