Graphs ā Representations & Fundamentals
š Concept
A graph is a collection of nodes (vertices) connected by edges. Graphs model relationships: social networks, maps, dependencies, state machines.
Graph types:
- Directed vs Undirected: One-way or two-way edges
- Weighted vs Unweighted: Edges have costs or all equal
- Cyclic vs Acyclic: Contains cycles or not (DAG = Directed Acyclic Graph)
- Dense vs Sparse: Many edges (|E| ā |V|²) or few (|E| ā |V|)
Representations:
- Adjacency List: Array/Map of lists ā O(V + E) space. Best for sparse graphs.
- Adjacency Matrix: 2D array ā O(V²) space. Best for dense graphs, quick edge lookup.
- Edge List: Array of [from, to, weight] ā simple but slow lookup.
Key algorithms:
- BFS: Level-by-level, shortest path in unweighted, O(V + E)
- DFS: Go deep, detect cycles, topological sort, O(V + E)
- Dijkstra: Shortest path, weighted (no negative), O((V+E) log V)
- Topological Sort: Order tasks with dependencies (DAG only)
- Union-Find: Connected components, cycle detection
š Real-world analogy: A city map. Intersections are vertices, roads are edges. One-way streets = directed. Road lengths = weights. Finding shortest route = Dijkstra. Finding if two cities are connected = BFS/DFS.
š» Code Example
1// GRAPH REPRESENTATIONS23// ADJACENCY LIST (most common)4function buildAdjList(n, edges) {5 const graph = new Map();6 for (let i = 0; i < n; i++) graph.set(i, []);7 for (const [from, to] of edges) {8 graph.get(from).push(to);9 graph.get(to).push(from); // Undirected10 }11 return graph;12}1314// ADJACENCY MATRIX15function buildAdjMatrix(n, edges) {16 const matrix = Array.from({length: n}, () => new Array(n).fill(0));17 for (const [from, to, weight = 1] of edges) {18 matrix[from][to] = weight;19 matrix[to][from] = weight; // Undirected20 }21 return matrix;22}2324// BFS ā O(V + E)25function bfs(graph, start) {26 const visited = new Set([start]);27 const queue = [start];28 const order = [];29 while (queue.length) {30 const node = queue.shift();31 order.push(node);32 for (const neighbor of graph.get(node) || []) {33 if (!visited.has(neighbor)) {34 visited.add(neighbor);35 queue.push(neighbor);36 }37 }38 }39 return order;40}4142// DFS ā O(V + E)43function dfs(graph, start) {44 const visited = new Set();45 const order = [];46 function explore(node) {47 visited.add(node);48 order.push(node);49 for (const neighbor of graph.get(node) || []) {50 if (!visited.has(neighbor)) explore(neighbor);51 }52 }53 explore(start);54 return order;55}5657// SHORTEST PATH ā BFS (unweighted)58function shortestPath(graph, start, end) {59 const visited = new Set([start]);60 const queue = [[start, 0]];61 while (queue.length) {62 const [node, dist] = queue.shift();63 if (node === end) return dist;64 for (const neighbor of graph.get(node) || []) {65 if (!visited.has(neighbor)) {66 visited.add(neighbor);67 queue.push([neighbor, dist + 1]);68 }69 }70 }71 return -1; // Not reachable72}7374// COUNT CONNECTED COMPONENTS75function countComponents(n, edges) {76 const graph = buildAdjList(n, edges);77 const visited = new Set();78 let count = 0;79 for (let i = 0; i < n; i++) {80 if (!visited.has(i)) {81 bfsVisit(graph, i, visited);82 count++;83 }84 }85 return count;86}8788function bfsVisit(graph, start, visited) {89 const queue = [start];90 visited.add(start);91 while (queue.length) {92 const node = queue.shift();93 for (const neighbor of graph.get(node) || []) {94 if (!visited.has(neighbor)) {95 visited.add(neighbor);96 queue.push(neighbor);97 }98 }99 }100}
šļø Practice Exercise
Practice Problems (Easy ā Hard):
- Build a graph from edge list using adjacency list
- BFS traversal ā print all nodes level by level
- DFS traversal ā recursive and iterative
- Find if a path exists between two nodes
- Count connected components in an undirected graph
- Detect a cycle in an undirected graph
- Detect a cycle in a directed graph
- Clone a graph (deep copy)
- Find all paths from source to target (DAG)
- Check if a graph is bipartite
ā ļø Common Mistakes
Forgetting the visited set ā leads to infinite loops in cyclic graphs
Using BFS for weighted shortest path ā BFS only works for unweighted; use Dijkstra for weighted
Not handling disconnected graphs ā BFS/DFS from one node may not reach all nodes
Confusing directed and undirected edge addition ā undirected adds both directions
Using adjacency matrix for sparse graphs ā wastes O(V²) space when O(V+E) suffices
š¼ Interview Questions
š¤ Mock Interview
Practice a live interview for Graphs ā Representations & Fundamentals