Skip to content

Commit f21e460

Browse files
authored
Added Kruskal's Algorithm (#232)
1 parent 3701b44 commit f21e460

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

Graphs/KruskalMST.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
class DisjointSetTreeNode {
2+
// Disjoint Set Node to store the parent and rank
3+
constructor (key) {
4+
this.key = key
5+
this.parent = this
6+
this.rank = 0
7+
}
8+
}
9+
10+
class DisjointSetTree {
11+
// Disjoint Set DataStructure
12+
constructor () {
13+
// map to from node name to the node object
14+
this.map = {}
15+
}
16+
17+
makeSet (x) {
18+
// Function to create a new set with x as its member
19+
this.map[x] = new DisjointSetTreeNode(x)
20+
}
21+
22+
findSet (x) {
23+
// Function to find the set x belongs to (with path-compression)
24+
if (this.map[x] !== this.map[x].parent) {
25+
this.map[x].parent = this.findSet(this.map[x].parent.key)
26+
}
27+
return this.map[x].parent
28+
}
29+
30+
union (x, y) {
31+
// Function to merge 2 disjoint sets
32+
this.link(this.findSet(x), this.findSet(y))
33+
}
34+
35+
link (x, y) {
36+
// Helper function for union operation
37+
if (x.rank > y.rank) {
38+
y.parent = x
39+
} else {
40+
x.parent = y
41+
if (x.rank === y.rank) {
42+
y.rank += 1
43+
}
44+
}
45+
}
46+
}
47+
48+
class GraphWeightedUndirectedAdjacencyList {
49+
// Weighted Undirected Graph class
50+
constructor () {
51+
this.connections = {}
52+
this.nodes = 0
53+
}
54+
55+
addNode (node) {
56+
// Function to add a node to the graph (connection represented by set)
57+
this.connections[node] = {}
58+
this.nodes += 1
59+
}
60+
61+
addEdge (node1, node2, weight) {
62+
// Function to add an edge (adds the node too if they are not present in the graph)
63+
if (!(node1 in this.connections)) { this.addNode(node1) }
64+
if (!(node2 in this.connections)) { this.addNode(node2) }
65+
this.connections[node1][node2] = weight
66+
this.connections[node2][node1] = weight
67+
}
68+
69+
KruskalMST () {
70+
// Kruskal's Algorithm to generate a Minimum Spanning Tree (MST) of a graph
71+
// Details: https://en.wikipedia.org/wiki/Kruskal%27s_algorithm
72+
// getting the edges in ascending order of weights
73+
const edges = []
74+
const seen = new Set()
75+
for (const start of Object.keys(this.connections)) {
76+
for (const end of Object.keys(this.connections[start])) {
77+
if (!seen.has(`${start} ${end}`)) {
78+
seen.add(`${end} ${start}`)
79+
edges.push([start, end, this.connections[start][end]])
80+
}
81+
}
82+
}
83+
edges.sort((a, b) => a[2] - b[2])
84+
// creating the disjoint set
85+
const disjointSet = new DisjointSetTree()
86+
Object.keys(this.connections).forEach(node => disjointSet.makeSet(node))
87+
// MST generation
88+
const graph = new GraphWeightedUndirectedAdjacencyList()
89+
let numEdges = 0
90+
let index = 0
91+
while (numEdges < this.nodes - 1) {
92+
const [u, v, w] = edges[index]
93+
index += 1
94+
if (disjointSet.findSet(u) !== disjointSet.findSet(v)) {
95+
numEdges += 1
96+
graph.addEdge(u, v, w)
97+
disjointSet.union(u, v)
98+
}
99+
}
100+
return graph
101+
}
102+
}
103+
104+
function main () {
105+
const graph = new GraphWeightedUndirectedAdjacencyList()
106+
graph.addEdge(1, 2, 1)
107+
graph.addEdge(2, 3, 2)
108+
graph.addEdge(3, 4, 1)
109+
graph.addEdge(3, 5, 100) // Removed in MST
110+
graph.addEdge(4, 5, 5)
111+
console.log(graph)
112+
console.log(graph.KruskalMST())
113+
}
114+
115+
main()

0 commit comments

Comments
 (0)