|
| 1 | +class UnionFind { |
| 2 | + constructor() { |
| 3 | + this.parent = new Map(); |
| 4 | + this.rank = new Map(); |
| 5 | + console.log("Initial parent map:", JSON.stringify([...this.parent])); |
| 6 | + console.log("Initial rank map:", JSON.stringify([...this.rank])); |
| 7 | + } |
| 8 | + |
| 9 | + add(x) { |
| 10 | + if (this.parent.has(x)) return; |
| 11 | + |
| 12 | + this.parent.set(x, x); |
| 13 | + this.rank.set(x, 1); |
| 14 | + } |
| 15 | + |
| 16 | + find(x) { |
| 17 | + console.log(`~~> Find(${x})`); |
| 18 | + |
| 19 | + // Find the root of the element x |
| 20 | + if (this.parent.get(x) !== x) { |
| 21 | + console.log(`Path compression for element ${x}`); |
| 22 | + this.parent.set(x, this.find(this.parent.get(x))); // Path compression |
| 23 | + } |
| 24 | + |
| 25 | + console.log(`Find(${x}) -> Root is ${this.parent.get(x)}`); |
| 26 | + return this.parent.get(x); |
| 27 | + } |
| 28 | + |
| 29 | + union(x, y) { |
| 30 | + console.log(`\nUnion(${x}, ${y})`); |
| 31 | + |
| 32 | + this.add(x); |
| 33 | + this.add(y); |
| 34 | + |
| 35 | + // Find the roots of x and y |
| 36 | + console.log(`~> before find:`, JSON.stringify([...this.parent])); |
| 37 | + let rootX = this.find(x); |
| 38 | + let rootY = this.find(y); |
| 39 | + |
| 40 | + if (rootX !== rootY) { |
| 41 | + console.log(`Union(${x}, ${y}) -> Already in the same set`); |
| 42 | + return; |
| 43 | + } |
| 44 | + |
| 45 | + let rankX = this.rank.get(rootX); |
| 46 | + let rankY = this.rank.get(rootY); |
| 47 | + |
| 48 | + console.log(`rootX: ${rootX}, \nrootY: ${rootY}, \nrankX: ${rankX}, \nrankY: ${rankY}`); |
| 49 | + console.log(`~~~> after find:`, JSON.stringify([...this.parent])); |
| 50 | + |
| 51 | + // If they have different roots, perform union |
| 52 | + if (rankX > rankY) { |
| 53 | + console.log(`(x <- y) -> Root of ${y} (root ${rootY}) attached to root ${rootX}`); |
| 54 | + this.parent.set(rootY, rootX); |
| 55 | + } else if (rankX < rankY) { |
| 56 | + console.log(`(x -> y) -> Root of ${x} (root ${rootX}) attached to root ${rootY}`); |
| 57 | + this.parent.set(rootX, rootY); |
| 58 | + } else { |
| 59 | + console.log(`(x <- y) -> Roots are equal, root ${rootY} attached to root ${rootX}`); |
| 60 | + this.parent.set(rootY, rootX); |
| 61 | + this.rank.set(rootX, rankX + 1); // ONLY increase the rank of the new root |
| 62 | + } |
| 63 | + |
| 64 | + console.log(`parent: ${JSON.stringify([...this.parent])}`); |
| 65 | + console.log(`rank: ${JSON.stringify([...this.rank])}`); |
| 66 | + } |
| 67 | +} |
| 68 | + |
| 69 | +// Create an instance of UnionFind with 8 elements (0 through 7) |
| 70 | +let uf = new UnionFind(); |
| 71 | + |
| 72 | +// Test Cases |
| 73 | +console.log("\nTest Case 1: Union operations"); |
| 74 | +// uf.union(1, 2); |
| 75 | +// uf.union(2, 3); |
| 76 | + |
| 77 | +uf.union(0, 0); |
| 78 | +uf.union(0, 1); |
| 79 | +uf.union(1, 0); |
| 80 | +uf.union(1, 2); |
| 81 | +uf.union(2, 1); |
| 82 | +uf.union(2, 2); |
| 83 | + |
| 84 | +// uf.union(4, 5); |
| 85 | +// uf.union(6, 7); |
| 86 | +// uf.union(5, 6); |
| 87 | +// uf.union(3, 7); // This will connect two previously separate sets |
| 88 | +// // console.log("\n--> size", uf.size()); |
| 89 | +// |
| 90 | +// console.log("\nTest Case 2: Find operations"); |
| 91 | +// console.log("\n- Find(1):", uf.find(1)); // Should compress path for 1 -> 2 -> 3 -> root |
| 92 | +// console.log("\n- Find(2):", uf.find(2)); // Already compressed |
| 93 | +// console.log("\n- Find(5):", uf.find(5)); // Should show the root of the 4-5-6-7 component |
| 94 | +// console.log("Find(8):", uf.find(8)); // 8 should be its own root (no connections yet) |
| 95 | +// |
| 96 | +// console.log("\nTest Case 3: Additional Unions and Finds"); |
| 97 | +// uf.union(8, 9); |
| 98 | +// console.log("Find(9):", uf.find(9)); // Should point to root after union with 8 |
| 99 | +// uf.union(3, 8); // This will connect the 1-2-3-7-6-5-4 set with 8-9 |
| 100 | +// console.log("Find(9):", uf.find(9)); // Should now point to the root of the entire connected set |
| 101 | +// console.log("Final parent array:", uf.parent); |
| 102 | +// console.log("Final rank array:", uf.rank); |
0 commit comments