class Graph {
adjacencyList: Map<number, number[]>;
constructor() {
this.adjacencyList = new Map();
}
addEdge(u: number, v: number) {
if (!this.adjacencyList.has(u)) this.adjacencyList.set(u, []);
this.adjacencyList.get(u)!.push(v);
}
shortestPath(start: number, end: number): number[] | null {
const queue: number[] = [start];
const visited = new Set<number>([start]);
const parent = new Map<number, number | null>();
parent.set(start, null);
while (queue.length > 0) {
const node = queue.shift()!;
if (node === end) {
const path: number[] = [];
let curr: number | null = end;
while (curr !== null) {
path.unshift(curr);
curr = parent.get(curr)!;
}
return path;
}
for (const neighbor of this.adjacencyList.get(node) || []) {
if (!visited.has(neighbor)) {
visited.add(neighbor);
parent.set(neighbor, node);
queue.push(neighbor);
}
}
}
return null;
}
}
// Driver code
const graph = new Graph();
graph.addEdge(1, 2);
graph.addEdge(2, 3);
graph.addEdge(1, 4);
graph.addEdge(4, 3);
const path = graph.shortestPath(1, 3);
if (path) {
console.log(path.join(' -> '));
} else {
console.log('No path found');
}const queue: number[] = [start];
Initialize queue with start node for BFS traversal
const visited = new Set<number>([start]);
Mark start node as visited to avoid revisiting
while (queue.length > 0) {
Process nodes level by level until queue is empty
const node = queue.shift()!;
Dequeue current node to explore neighbors
if (node === end) { ... }
If end node reached, reconstruct path using parent map
for (const neighbor of this.adjacencyList.get(node) || []) {
Explore all neighbors of current node
if (!visited.has(neighbor)) { ... }
Visit unvisited neighbors, mark visited, and enqueue