class DisjointSet {
parent: number[];
rank: number[];
constructor(n: number) {
this.parent = Array(n).fill(0).map((_, i) => i);
this.rank = Array(n).fill(0);
}
find(x: number): number {
if (this.parent[x] !== x) {
this.parent[x] = this.find(this.parent[x]); // path compression
}
return this.parent[x];
}
union(x: number, y: number): boolean {
let rootX = this.find(x);
let rootY = this.find(y);
if (rootX === rootY) return false; // cycle detected
if (this.rank[rootX] < this.rank[rootY]) {
this.parent[rootX] = rootY;
} else if (this.rank[rootX] > this.rank[rootY]) {
this.parent[rootY] = rootX;
} else {
this.parent[rootY] = rootX;
this.rank[rootX]++;
}
return true;
}
}
interface Edge {
from: number;
to: number;
weight: number;
}
function kruskalMST(nodesCount: number, edges: Edge[]): Edge[] {
edges.sort((a, b) => a.weight - b.weight); // sort edges by weight
const ds = new DisjointSet(nodesCount);
const mst: Edge[] = [];
for (const edge of edges) {
if (ds.union(edge.from, edge.to)) {
mst.push(edge); // add edge if no cycle
}
}
return mst;
}
// Driver code
// Map nodes A=0, B=1, C=2, D=3
const edges: Edge[] = [
{ from: 0, to: 1, weight: 2 }, // A-B
{ from: 1, to: 3, weight: 1 }, // B-D
{ from: 0, to: 2, weight: 3 }, // A-C
{ from: 2, to: 3, weight: 4 } // C-D
];
const mst = kruskalMST(4, edges);
for (const e of mst) {
console.log(`Edge from ${String.fromCharCode(65 + e.from)} to ${String.fromCharCode(65 + e.to)} with weight ${e.weight}`);
}edges.sort((a, b) => a.weight - b.weight);
Sort edges by weight ascending to pick smallest edges first
if (ds.union(edge.from, edge.to)) {
Add edge only if it connects two different sets (no cycle)
this.parent[x] = this.find(this.parent[x]);
Path compression to speed up find operation
Edge from B to D with weight 1
Edge from A to B with weight 2
Edge from A to C with weight 3