Bird
Raised Fist0
DSA Typescriptprogramming~10 mins

DFS Depth First Search on Graph in DSA Typescript - Execution Trace

Choose your learning style10 modes available
Concept Flow - DFS Depth First Search on Graph
Start at root node
↓
Mark node as visited
↓
Explore first unvisited neighbor
↓
Recursive DFS call on neighbor
↓
All neighbors visited?
No→Repeat for next neighbor
Yes↓
Backtrack to previous node
↓
All nodes visited?
No→Continue
Yes↓
End
Start from a node, visit it, then recursively visit each unvisited neighbor deeply before backtracking.
Execution Sample
DSA Typescript
function dfs(node, visited) {
  visited.add(node);
  for (const neighbor of graph[node]) {
    if (!visited.has(neighbor)) dfs(neighbor, visited);
  }
}
This code visits a node, marks it visited, then recursively visits all unvisited neighbors.
Execution Table
StepOperationCurrent NodeVisited SetStack (Call Trace)Action TakenGraph State
1Start DFSA{}[]Visit AA: [B, C], B: [D], C: [E], D: [], E: []
2Visit NodeA{A}[A]Mark A visitedSame
3Explore neighborA{A}[A]Check neighbor BSame
4Visit NodeB{A}[A, B]Mark B visitedSame
5Explore neighborB{A, B}[A, B]Check neighbor DSame
6Visit NodeD{A, B}[A, B, D]Mark D visitedSame
7Explore neighborD{A, B, D}[A, B, D]No neighbors to visitSame
8BacktrackD{A, B, D}[A, B]Return to BSame
9All neighbors visited?B{A, B, D}[A, B]Yes, backtrackSame
10BacktrackB{A, B, D}[A]Return to ASame
11Explore neighborA{A, B, D}[A]Check neighbor CSame
12Visit NodeC{A, B, D}[A, C]Mark C visitedSame
13Explore neighborC{A, B, D, C}[A, C]Check neighbor ESame
14Visit NodeE{A, B, D, C}[A, C, E]Mark E visitedSame
15Explore neighborE{A, B, D, C, E}[A, C, E]No neighbors to visitSame
16BacktrackE{A, B, D, C, E}[A, C]Return to CSame
17All neighbors visited?C{A, B, D, C, E}[A, C]Yes, backtrackSame
18BacktrackC{A, B, D, C, E}[A]Return to ASame
19All neighbors visited?A{A, B, D, C, E}[A]Yes, DFS completeSame
20End DFS-{A, B, D, C, E}[]All nodes visitedSame
💡 All nodes visited, no unvisited neighbors remain, DFS ends
Variable Tracker
VariableStartAfter Step 2After Step 4After Step 6After Step 12After Step 14Final
visited{}{A}{A, B}{A, B, D}{A, B, D, C}{A, B, D, C, E}{A, B, D, C, E}
stack[][A][A, B][A, B, D][A, C][A, C, E][]
current_node-ABDCE-
Key Moments - 3 Insights
Why do we mark a node as visited before exploring its neighbors?
Marking a node visited early (see Step 2) prevents revisiting it during neighbor checks (Step 3), avoiding infinite loops.
Why do we backtrack after visiting all neighbors?
Backtracking (Steps 8, 10, 16, 18) happens when no unvisited neighbors remain, so DFS returns to previous nodes to explore other paths.
Why does the stack grow and shrink during DFS?
The stack (call trace) grows when DFS goes deeper (Steps 4, 6, 12, 14) and shrinks when backtracking (Steps 8, 10, 16, 18), reflecting recursion depth.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the visited set after Step 6?
A{A, B}
B{A, B, D}
C{A, B, C}
D{A, B, D, C}
💡 Hint
Check the 'Visited Set' column at Step 6 in the execution table.
At which step does DFS first backtrack from node D?
AStep 8
BStep 7
CStep 9
DStep 10
💡 Hint
Look for 'Backtrack' operation with current node D in the execution table.
If node E had a neighbor F not visited yet, what would happen at Step 15?
ADFS would skip F and finish
BDFS would backtrack immediately
CDFS would visit F next, stack grows
DDFS would restart from A
💡 Hint
At Step 15, DFS explores neighbors; unvisited neighbors cause recursive calls and stack growth.
Concept Snapshot
DFS visits nodes deeply before backtracking.
Start at a node, mark visited.
Recursively visit unvisited neighbors.
Use stack (call trace) to track path.
Backtrack when no neighbors left.
Ends when all reachable nodes visited.
Full Transcript
Depth First Search (DFS) starts at a chosen node, marks it visited, then explores each neighbor deeply before backtracking. The process uses recursion, which acts like a stack to remember the path. Each step marks nodes visited to avoid repeats. When a node has no unvisited neighbors, DFS backtracks to explore other paths. This continues until all nodes reachable from the start are visited. The execution table shows each step, the current node, visited nodes, and the call stack. Key moments include marking visited early to prevent loops, backtracking when no neighbors remain, and stack changes reflecting recursion depth.

Practice

(1/5)
1. What is the main idea behind Depth First Search (DFS) on a graph?
easy
A. Explore as far as possible along each branch before backtracking
B. Visit all neighbors of a node before moving deeper
C. Visit nodes in order of their distance from the start node
D. Randomly visit nodes until all are visited

Solution

  1. Step 1: Understand DFS traversal strategy

    DFS explores nodes by going deep into one branch before backtracking to explore other branches.
  2. Step 2: Compare with other traversal methods

    BFS visits neighbors first, but DFS goes deep first, matching Explore as far as possible along each branch before backtracking.
  3. Final Answer:

    Explore as far as possible along each branch before backtracking -> Option A
  4. Quick Check:

    DFS = deep exploration first [OK]
Hint: DFS goes deep first, BFS goes wide first [OK]
Common Mistakes:
  • Confusing DFS with BFS
  • Thinking DFS visits neighbors first
  • Assuming DFS visits nodes by distance
2. Which of the following is the correct TypeScript function signature for a DFS function on a graph represented as an adjacency list?
easy
A. function dfs(graph: Map, start: number): void
B. function dfs(graph: number[], start: number): void
C. function dfs(graph: number[][], start: number): void
D. function dfs(graph: string[][], start: string): void

Solution

  1. Step 1: Identify graph representation type

    An adjacency list for a graph with numbered nodes is usually number[][], where each index holds neighbors.
  2. Step 2: Check parameter types

    Start node is a number, so function signature with graph: number[][] and start: number is correct.
  3. Final Answer:

    function dfs(graph: number[][], start: number): void -> Option C
  4. Quick Check:

    Adjacency list = number[][], start node = number [OK]
Hint: Adjacency list uses array of arrays for neighbors [OK]
Common Mistakes:
  • Using number[] instead of number[][] for adjacency list
  • Using Map with incorrect value type
  • Using string types for numeric graphs
3. What is the output of the following DFS traversal starting from node 0?
const graph = [[1, 2], [2], [0, 3], [3]];
const visited: boolean[] = [];
const result: number[] = [];
function dfs(node: number) {
  if (visited[node]) return;
  visited[node] = true;
  result.push(node);
  for (const neighbor of graph[node]) {
    dfs(neighbor);
  }
}
dfs(0);
console.log(result);
medium
A. [0, 2, 3, 1]
B. [0, 2, 1, 3]
C. [0, 1, 2]
D. [0, 1, 2, 3]

Solution

  1. Step 1: Start DFS at node 0

    Visit 0, mark visited, add to result: [0]. Neighbors: 1, 2.
  2. Step 2: Visit neighbor 1

    Visit 1, mark visited, add: [0,1]. Neighbor: 2.
  3. Step 3: Visit neighbor 2 from 1

    Visit 2, mark visited, add: [0,1,2]. Neighbors: 0 (visited), 3.
  4. Step 4: Visit neighbor 3 from 2

    Visit 3, mark visited, add: [0,1,2,3]. Neighbor: 3 (already visited).
  5. Final Answer:

    [0, 2, 1, 3] -> Option B
  6. Quick Check:

    DFS order = [0,2,1,3] [OK]
Hint: Follow neighbors recursively, mark visited to avoid repeats [OK]
Common Mistakes:
  • Not marking nodes visited before recursion
  • Visiting neighbors in wrong order
  • Ignoring already visited nodes
4. Identify the bug in this DFS implementation and choose the fix:
function dfs(node: number, graph: number[][], visited: boolean[]) {
  visited[node] = true;
  for (const neighbor of graph[node]) {
    if (!visited[neighbor]) {
      dfs(neighbor, graph, visited);
    }
  }
}

const graph = [[1], [2], [0]];
const visited = new Array(graph.length).fill(false);
dfs(0, graph, visited);
console.log(visited);
medium
A. Mark visited[node] = true after recursive calls
B. Initialize visited array with true instead of false
C. Add a base case to return if node is already visited at start
D. No bug, code works correctly

Solution

  1. Step 1: Check visited marking timing

    Visited[node] is marked true before recursion, preventing revisits.
  2. Step 2: Verify recursion and base case

    Recursion only happens if neighbor not visited, so no infinite loops.
  3. Final Answer:

    No bug, code works correctly -> Option D
  4. Quick Check:

    Visited marked before recursion = correct DFS [OK]
Hint: Mark visited before recursion to avoid cycles [OK]
Common Mistakes:
  • Marking visited after recursion causing infinite loops
  • Initializing visited array incorrectly
  • Missing base case check
5. Given a graph with possible cycles, how can you modify DFS to detect if a cycle exists starting from a given node? Choose the best approach.
hard
A. Use a recursion stack array to track nodes in the current path and detect back edges
B. Only mark nodes visited after all neighbors are visited
C. Use BFS instead of DFS to detect cycles
D. Ignore visited nodes and continue traversal

Solution

  1. Step 1: Understand cycle detection in DFS

    Detecting cycles requires knowing if a node is in the current recursion path (stack).
  2. Step 2: Use recursion stack tracking

    Maintain a separate array to track nodes currently in recursion; if a neighbor is in this stack, a cycle exists.
  3. Step 3: Evaluate other options

    Marking visited after neighbors or using BFS won't reliably detect cycles; ignoring visited nodes causes infinite loops.
  4. Final Answer:

    Use a recursion stack array to track nodes in the current path and detect back edges -> Option A
  5. Quick Check:

    Cycle detection = recursion stack tracking [OK]
Hint: Track recursion path to find back edges indicating cycles [OK]
Common Mistakes:
  • Not tracking recursion stack causing missed cycles
  • Using BFS which doesn't track recursion path
  • Marking visited too late or ignoring visited nodes
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard