Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Graphs/test/DepthFirstSearchIterative.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { GraphUnweightedUndirected } from '../DepthFirstSearchIterative.js'

test('DFSIterative finds existing value and rejects non-existing', () => {
const g = new GraphUnweightedUndirected()
g.addEdge(1, 2)
g.addEdge(2, 3)
g.addEdge(2, 4)
g.addEdge(3, 5)

expect(g.DFSIterative(5, 1)).toBe(true) // path 5->3->2->1 exists
expect(g.DFSIterative(5, 100)).toBe(false) // 100 not in graph
})
12 changes: 12 additions & 0 deletions Graphs/test/DepthFirstSearchRecursive.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { GraphUnweightedUndirected } from '../DepthFirstSearchRecursive.js'

test('DFSRecursive finds existing value and rejects non-existing', () => {
const g = new GraphUnweightedUndirected()
g.addEdge(1, 2)
g.addEdge(2, 3)
g.addEdge(2, 4)
g.addEdge(3, 5)

expect(g.DFSRecursive(5, 1)).toBe(true) // path 5->3->2->1 exists
expect(g.DFSRecursive(5, 100)).toBe(false) // 100 not in graph
})
33 changes: 33 additions & 0 deletions Graphs/test/Dijkstra.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { createGraph, djikstra } from '../Dijkstra.js'

// Undirected weighted graph
// 0 --2-- 1 --3-- 3 --4-- 4
// | | \
// 5| 1 1
// | |
// 2 ---- 2 ---------
// From source 0, shortest distances should be:
// 0:0, 1:2, 2:3 (0->1->2), 3:4 (0->1->2->3), 4:8 (0->1->2->3->4)

test('Dijkstra shortest distances from source 0', () => {
const V = 5
const E = [
[0, 1, 2],
[0, 2, 5],
[1, 2, 1],
[1, 3, 3],
[2, 3, 1],
[3, 4, 4]
]

const graph = createGraph(V, E)
const dist = djikstra(graph, V, 0)

const expected = [0, 2, 3, 4, 8]
for (let i = 0; i < V; i++) {
expect(dist[i][0]).toBe(expected[i])
}

// parent of source should be -1 by implementation
expect(dist[0][1]).toBe(-1)
})
30 changes: 30 additions & 0 deletions Graphs/test/DijkstraSmallestPath.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { solve } from '../DijkstraSmallestPath.js'

// Graph represented as adjacency object where graph[u][v] = weight
// Example graph:
// A --1-- B --2-- C
// \3 \
// \ 5
// \--4-- D -----
// Shortest distances from A: A:0, B:1, C:3 (A->B->C), D:4 (A->D)

test('DijkstraSmallestPath returns shortest distances and paths', () => {
const graph = {
A: { B: 1, D: 4 },
B: { A: 1, C: 2 },
C: { B: 2, D: 5 },
D: { A: 4, C: 5 }
}

const res = solve(graph, 'A')

expect(res.A.dist).toBe(0)
expect(res.B.dist).toBe(1)
expect(res.C.dist).toBe(3)
expect(res.D.dist).toBe(4)

// Path arrays exclude the source by implementation (solutions[s] = [])
expect([...res.B]).toEqual(['B'])
expect([...res.C]).toEqual(['B', 'C'])
expect([...res.D]).toEqual(['D'])
})
19 changes: 19 additions & 0 deletions Graphs/test/FloydWarshall.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FloydWarshall } from '../FloydWarshall.js'

test('FloydWarshall computes all-pairs shortest paths', () => {
const INF = Infinity
const dist = [
[0, 1, 2, INF],
[1, 0, INF, INF],
[2, INF, 0, 1],
[INF, INF, 1, 0]
]

const out = FloydWarshall(dist)
expect(out).toEqual([
[0, 1, 2, 3],
[1, 0, 3, 4],
[2, 3, 0, 1],
[3, 4, 1, 0]
])
})
55 changes: 55 additions & 0 deletions Graphs/test/KruskalMST.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { GraphWeightedUndirectedAdjacencyList } from '../KruskalMST.js'

function totalWeight(graph) {
// connections: { u: { v: w, ... }, ... }
let sum = 0
const seen = new Set()
for (const u of Object.keys(graph.connections)) {
for (const v of Object.keys(graph.connections[u])) {
const key = u < v ? `${u}-${v}` : `${v}-${u}`
if (!seen.has(key)) {
seen.add(key)
sum += graph.connections[u][v]
}
}
}
return sum
}

test('KruskalMST builds a minimum spanning tree', () => {
const g = new GraphWeightedUndirectedAdjacencyList()
// Graph:
// 1-2(1), 2-3(2), 3-4(1), 3-5(100), 4-5(5)
g.addEdge('1', '2', 1)
g.addEdge('2', '3', 2)
g.addEdge('3', '4', 1)
g.addEdge('3', '5', 100) // heavy edge to be excluded
g.addEdge('4', '5', 5)

const mst = g.KruskalMST()

// MST should have nodes: 1,2,3,4,5
expect(Object.keys(mst.connections).sort()).toEqual(['1', '2', '3', '4', '5'])

// It should have exactly nodes-1 = 4 edges
let edgeCount = 0
const seen = new Set()
for (const u of Object.keys(mst.connections)) {
for (const v of Object.keys(mst.connections[u])) {
const key = u < v ? `${u}-${v}` : `${v}-${u}`
if (!seen.has(key)) {
seen.add(key)
edgeCount++
}
}
}
expect(edgeCount).toBe(4)

// Total weight should be 1 (1-2) + 2 (2-3) + 1 (3-4) + 5 (4-5) = 9
// (Edge 3-5 with weight 100 must not be selected)
expect(totalWeight(mst)).toBe(9)

// Ensure excluded heavy edge is not present
expect(mst.connections['3']['5']).toBeUndefined()
expect(mst.connections['5']['3']).toBeUndefined()
})