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, []);
if (!this.adjacencyList.has(v)) this.adjacencyList.set(v, []);
this.adjacencyList.get(u)!.push(v);
this.adjacencyList.get(v)!.push(u);
}
private dfs(node: number, visited: Set<number>, parent: number | null): boolean {
visited.add(node); // mark current node visited
for (const neighbor of this.adjacencyList.get(node) || []) {
if (!visited.has(neighbor)) {
if (this.dfs(neighbor, visited, node)) return true; // cycle found deeper
} else if (neighbor !== parent) {
return true; // visited neighbor not parent means cycle
}
}
return false; // no cycle found from this path
}
hasCycle(): boolean {
const visited = new Set<number>();
for (const node of this.adjacencyList.keys()) {
if (!visited.has(node)) {
if (this.dfs(node, visited, null)) return true; // cycle detected
}
}
return false; // no cycle in any component
}
}
// Driver code
const graph = new Graph();
graph.addEdge(1, 2);
graph.addEdge(2, 3);
graph.addEdge(3, 4);
graph.addEdge(4, 1);
console.log(graph.hasCycle() ? "Cycle detected" : "No cycle detected");visited.add(node); // mark current node visited
Mark the current node as visited to avoid revisiting
if (!visited.has(neighbor)) { if (this.dfs(neighbor, visited, node)) return true; }
Explore unvisited neighbors recursively to find cycles
else if (neighbor !== parent) { return true; }
If neighbor is visited and not parent, cycle is found
for (const node of this.adjacencyList.keys()) { if (!visited.has(node)) { if (this.dfs(node, visited, null)) return true; } }
Check all graph components for cycles