What if your family tree can't show all your friends and their friends? That's why graphs exist!
Why Graphs Exist and What Trees Cannot Model in DSA Typescript - The Real Reason
Imagine you want to map all the roads connecting cities in a country. You try to draw it like a family tree, but soon realize many cities connect back and forth, not just in a straight line.
Using a tree-like structure here is slow and confusing because trees only allow one path between points. Roads often loop and connect in many ways, so trees can't show all connections properly.
Graphs let you connect points in any way you want. They can show loops, multiple paths, and complex networks easily, making it perfect for mapping roads, social networks, or web links.
class TreeNode { value: string; children: TreeNode[]; constructor(value: string) { this.value = value; this.children = []; } } // Trying to connect cities with multiple roads is hard here
class Graph { adjacencyList: Map<string, string[]> = new Map(); addEdge(city1: string, city2: string) { if (!this.adjacencyList.has(city1)) this.adjacencyList.set(city1, []); this.adjacencyList.get(city1)!.push(city2); if (!this.adjacencyList.has(city2)) this.adjacencyList.set(city2, []); this.adjacencyList.get(city2)!.push(city1); } } // Easily connect cities with many roads
Graphs let us model real-world networks with complex connections that trees simply cannot represent.
Social media platforms use graphs to show how friends connect, follow, and interact with each other in many ways, not just in a simple hierarchy.
Trees only allow one path between points, limiting complex connections.
Graphs support loops and multiple connections, modeling real networks.
Graphs are essential for representing roads, social networks, and web links.
Practice
Solution
Step 1: Understand tree limitations
Trees are hierarchical and cannot have cycles or multiple parents for a node.Step 2: Understand graph capabilities
Graphs allow any connections, including cycles and multiple edges between nodes.Final Answer:
Because graphs can represent connections between nodes in any pattern, including cycles. -> Option DQuick Check:
Graphs model cycles, trees cannot [OK]
- Thinking trees can have cycles
- Confusing data types with structure
- Assuming graphs are simpler than trees
Solution
Step 1: Identify adjacency list type
An adjacency list is an array of arrays, where each inner array holds connected node indices.Step 2: Match TypeScript syntax
TypeScript syntax for adjacency list is number[][] for array of number arrays.Final Answer:
const graph: number[][] = []; -> Option BQuick Check:
Adjacency list = number[][] [OK]
- Using single number type for adjacency list
- Using object {} instead of array []
- Wrong type annotations
const graph: number[][] = [[1], [2], [0]];
function hasCycle(node: number, visited: boolean[], stack: boolean[]): boolean {
if (!visited[node]) {
visited[node] = true;
stack[node] = true;
for (const neighbor of graph[node]) {
if (!visited[neighbor] && hasCycle(neighbor, visited, stack)) {
return true;
} else if (stack[neighbor]) {
return true;
}
}
}
stack[node] = false;
return false;
}
const visited = [false, false, false];
const stack = [false, false, false];
console.log(hasCycle(0, visited, stack));
What is the output?Solution
Step 1: Understand graph structure
Graph edges: 0->1, 1->2, 2->0 form a cycle.Step 2: Trace hasCycle function
DFS visits nodes 0,1,2 and detects back edge from 2 to 0 in recursion stack, returning true.Final Answer:
true -> Option CQuick Check:
Cycle detected = true [OK]
- Assuming no cycle in small graph
- Confusing visited and stack arrays
- Ignoring recursion stack usage
const graph: number[][] = [[1], [2], [0]];
function hasCycle(node: number, visited: boolean[], stack: boolean[]): boolean {
if (visited[node]) {
return false;
}
visited[node] = true;
stack[node] = true;
for (const neighbor of graph[node]) {
if (!visited[neighbor] && hasCycle(neighbor, visited, stack)) {
return true;
} else if (stack[neighbor]) {
return true;
}
}
stack[node] = false;
return false;
}
const visited = [false, false, false];
const stack = [false, false, false];
console.log(hasCycle(0, visited, stack));
What is the bug in this code?Solution
Step 1: Analyze early return on visited node
Returning false immediately when node is visited skips cycle detection on back edges.Step 2: Understand correct cycle detection logic
Should only return false if node visited and not in recursion stack; else return true if in stack.Final Answer:
It returns false immediately if node is visited, missing cycles. -> Option AQuick Check:
Early return on visited node causes missed cycles [OK]
- Returning false too early
- Confusing visited and recursion stack
- Ignoring recursion stack check
Solution
Step 1: Identify social network connection patterns
Users can follow each other in any pattern, including cycles and mutual connections.Step 2: Compare data structures
Trees cannot represent cycles or multiple parents; graphs can represent any connection pattern.Final Answer:
Use a graph because it supports cycles and multiple connections; trees cannot model cycles or multiple parents. -> Option AQuick Check:
Graphs model social networks; trees cannot [OK]
- Choosing tree for cyclic connections
- Confusing linked list with graph
- Ignoring cycles in social networks
Ready to prove it?
Pass the test and this pattern moves unknown
