Binary Tree DFS (Depth-First Search)

Tree Selection

Playback Controls

Frame 1 of 1
Loading DFS tree visualization...
Time: O(n)
Space: O(h)

Algorithm Progress

Tree Nodes: 7
Tree Edges: 6
Traversal: preorder
Search Target: None (Full Traversal)

Reference implementation of DFS (Depth-First Search). Select a language tab to view and copy the code.

def dfs(adj: list[list[int]], visited: list[bool], node: int) -> None:
    visited[node] = True
    # process node
    for neighbor in adj[node]:
        if not visited[neighbor]:
            dfs(adj, visited, neighbor)


def dfs_iterative(adj: list[list[int]], start: int) -> list[int]:
    visited = [False] * len(adj)
    order, stack = [], [start]
    while stack:
        node = stack.pop()
        if visited[node]:
            continue
        visited[node] = True
        order.append(node)
        for neighbor in adj[node]:
            if not visited[neighbor]:
                stack.append(neighbor)
    return order

Python — Code Walkthrough

  1. visited passed in — no global state

    def dfs(adj, visited, node)

    Passing visited explicitly avoids global state, making the function pure and testable. Callers can reuse the same visited array across multiple DFS calls (e.g., for disconnected graphs).

  2. Python recursion limit

    dfs(adj, visited, neighbor)

    Python has a default recursion limit of 1000. For large graphs, use sys.setrecursionlimit() or prefer the iterative version to avoid RecursionError.

  3. stack.pop() for LIFO

    node = stack.pop()

    list.pop() removes from the end (O(1)) — LIFO behavior. This is the key difference from BFS which uses deque.popleft() — FIFO behavior.

  4. Check visited on pop in iterative version

    if visited[node]: continue

    Multiple neighbors can push the same node before it is visited. Skipping on pop handles this correctly without extra bookkeeping at push time.