Home/Learn/Math for AI/Graphs, Trees & Traversal (BFS/DFS)

Graphs, Trees & Traversal (BFS/DFS)

Intermediate
Discrete Math & Graphs

Graphs model entities and their relationships; traversals like BFS and DFS explore them — the structures behind knowledge graphs, recommendation engines, and graph neural networks.

Overview

A graph is a set of nodes connected by edges — the natural model for anything relational: social networks, knowledge graphs, molecules, web links, and recommendation systems (users and items as nodes). Trees are a special acyclic case used for hierarchies, parsing, and decision trees. Two traversals are fundamental: breadth-first search (BFS) explores level by level and finds shortest paths in unweighted graphs, while depth-first search (DFS) plunges down one path before backtracking and is used for reachability, cycle detection, and topological ordering of DAGs (which model task/computation dependencies). Directed acyclic graphs are especially relevant to AI: the computation graph a framework builds for autograd is a DAG, and pipelines/dependencies are DAGs too. Graph Neural Networks generalise deep learning to this structure, letting nodes aggregate information from their neighbours — powering fraud detection, molecule property prediction, and modern recommenders.

Represent a graph and traverse it (BFS)

An adjacency map lists each node's neighbours. BFS uses a queue to explore outward level by level — the basis of shortest-path and "degrees of separation".

BFS with a queue — shortest paths in unweighted graphs
from collections import deque

graph = {
    "A": ["B", "C"], "B": ["A", "D"],
    "C": ["A", "D"], "D": ["B", "C", "E"], "E": ["D"],
}

def bfs(start):
    seen, order, q = {start}, [], deque([start])
    while q:
        node = q.popleft()
        order.append(node)
        for nb in graph[node]:
            if nb not in seen:
                seen.add(nb); q.append(nb)
    return order

print(bfs("A"))   # ['A','B','C','D','E'] level by level

DFS and DAGs: dependency ordering

DFS goes deep before backtracking. On a directed acyclic graph it yields a topological order — the sequence in which dependent tasks (or autograd operations) must run.

DFS on a DAG → topological (dependency) order
deps = {                      # a DAG of task dependencies
    "data": [], "clean": ["data"],
    "train": ["clean"], "eval": ["train"], "deploy": ["eval"],
}

def toposort(g):
    seen, order = set(), []
    def dfs(n):
        if n in seen: return
        seen.add(n)
        for m in g[n]: dfs(m)
        order.append(n)          # add after visiting dependencies
    for n in g: dfs(n)
    return order

print(toposort(deps))   # ['data','clean','train','eval','deploy']

Key Points to Remember

  • 1Graphs = nodes + edges; the model for relational data (social, knowledge, recommenders)
  • 2BFS explores level by level (shortest paths); DFS goes deep (reachability, cycles)
  • 3DAGs model dependencies — including the autograd computation graph
  • 4Graph Neural Networks let nodes aggregate neighbour info — fraud, molecules, recommendations

Interview Questions

Sign in to ask Aria
1

When would you use BFS versus DFS?

MediumAmazon
2

What is a topological sort and what must be true of the graph for one to exist?

MediumGoogle
3

How do Graph Neural Networks extend deep learning to graph data?

HardProduct

Ask Aria about Graphs, Trees & Traversal (BFS/DFS)

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…