Skip to content
ByteStepStart with recursion

Graph traversal: BFS and DFS

Free, no account

A graph is a set of places and the connections between them. Cities and roads, people and friendships, pages and links, rooms and doors. Each place is a node, each connection an edge, and almost every interesting question about one of them starts with the same move: walk it.

There are two famous ways to walk a graph, and they are taught as two algorithms with two names. They are not. They are one algorithm, and below you can watch the difference arrive: switch between the first two buttons and exactly one line of code changes.

Keep an eye on the container on the right. Everywhere the search knows about and has not been to yet waits in it. Which end it is emptied from is the entire difference between the two names.

1function search(graph, start) {
2 const frontier = [start]
3 const seen = new Set()
4 while (frontier.length > 0) {
5 const node = frontier.shift() // from the front
6 if (seen.has(node)) continue
7 seen.add(node)
8 for (const next of graph[node])
9 if (!seen.has(next)) frontier.push(next)
10 }
11}

The graph

numbered in visit order; violet is waiting, dashed is unreached

Taking from the front

ABCDEFGH

0 of 8 visited

The container · a queue

everywhere known about and not yet visited

  1. Anext out

1 place

Starting at A. It goes into the container on its own, and everything else follows from what comes out.

1/12
Detail
12 steps

The one algorithm, the one line that splits it in two, and why the visited set is what makes it finish.

One algorithm

Put the starting place in a container. Then repeat: take one out, mark it as visited, and put each of its neighbours in. Stop when the container is empty. That is the whole thing, and it is the same four lines whichever search you are doing.

The container of places you know about and have not visited is called the frontier, which is a good name: it really is the edge of what has been explored, and it moves outward as the search runs.

The one line

Take from the front of the frontier and the oldest place waiting comes out first. Everything one step from the start is dealt with before anything two steps away, so the search spreads outward in rings. That is breadth-first search, and starting from A it visits A B C D E F G H.

Take from the back and the newest place comes out first, which is always somewhere you have only just heard about. The search commits to whatever it found most recently and runs to the end of that path before it considers anything else. That is depth-first search, and from the same A it visits A C F H G D B E.

A queue gives you one, a stack gives you the other, and nothing else changes. If that seems like too small a difference to deserve two names and two lectures, it is worth sitting with: it is exactly that small, and the consequences are not small at all.

Why the visited set is not bookkeeping

A graph can contain a cycle: a path that leaves a node and comes back to it. A and B are joined, so from A you can reach B, and from B you can reach A, forever.

The visited set is what stops that. Press the third button and watch a search with the check removed: the frontier grows faster than it empties, the same nodes come round again and again, and after 22 turns it has made no progress across a graph of only 8 nodes. It is cut off there because otherwise it would run until the tab died.

This is why a graph is harder than a call tree. A tree has no cycles, so a walk over it cannot revisit anything and needs no memory of where it has been. Add one edge that closes a loop and that stops being true.

Know someone stuck on this? Send it to them.

A classmate, a study group, someone learning this on their own at midnight. The link opens the lesson set up exactly as you have it, the same function and the same number, and runs from the first step so they watch the whole thing build rather than landing in the middle of it.

Also in this course

Recursion: how a function calls itself

Depth-first search written recursively has no visible container at all. The stack is still there; it is the one this lesson draws.

Start there →