BFS and DFS visualizer

Breadth-first search explores a graph in rings around the start; depth-first search runs down one path as far as it goes, then backs up. Step through either on the same graph and watch the queue or the stack that drives it.

Visited
0 of 12
Queue
0
Peak
4
Search
Graph
Step 0 of 50 · click a node to start there
A B C D E F G H I J K L

not seen in the queue visited tree edge

Press Play or Step. Breadth-first search will start from A. Click a node to start somewhere else.

Queue (front on the left)
empty
Visit order
none yet
d on a node
edges from A (shortest)
Farthest node
4 edges
Edges
13, each checked twice

How to use the simulator

Choose a search and a graph, then press Play or Step. Click any node to start from it. Each step is one of four things: a node joins the queue or stack, a node is taken off and visited, an edge is examined, or (in DFS) a node is finished because all its neighbours are done. Neighbours are always tried in alphabetical order. BFS labels each node with its distance from the start; DFS labels it with its discovery time and, once finished, its finish time, counted on one clock that ticks at every discovery and every finish.

Try these:

  • Run BFS on the Tree, then DFS. BFS fills in each level before the next; DFS runs down the left side first. Compare the peak sizes of the queue and the stack.
  • Run both on the Grid. BFS spreads in a diagonal wave, and the distance labels are the shortest paths. DFS snakes through the whole grid on one long path, so its stack grows to 20 nodes.
  • On Branching, watch for edges whose far end was already seen. In DFS each such edge leads back to a node on the current path, an ancestor; that is what makes DFS useful for finding cycles.

The searches are tested on thousands of random graphs: BFS distances match shortest-path lengths, and the DFS order matches a recursive depth-first search exactly.

What is graph traversal?

Graph traversal means visiting every node of a graph that can be reached from a starting node, each exactly once. A graph is a set of nodes connected by edges: a road map, a social network, the links between web pages, the states of a puzzle, the cells of a maze. Breadth-first search and depth-first search are the two basic ways to do it, and many other graph algorithms are one of them with extra bookkeeping.

Both keep track of which nodes have been seen, so that cycles do not send them round forever, and both keep a frontier of nodes still to explore. The only difference is which frontier node they take next: the oldest (BFS, a queue) or the newest (DFS, a stack).

Breadth-first search

BFS puts the start node in a queue and marks it seen. Then, until the queue is empty, it takes the node at the front and adds each of its unseen neighbours to the back, marking them seen as they go in. Because the queue is first in, first out, every node at distance 1 is taken out before any node at distance 2, and so on: the search moves outward in layers.

That gives BFS its main property. The first time it reaches a node is along a path with the fewest possible edges, so recording each node's parent when it is discovered gives a shortest-path tree. Marking nodes when they enter the queue, not when they leave it, matters: it keeps each node in the queue at most once.

On the Branching graph from A, BFS visits A B C D E F G H I J K L.

Depth-first search

DFS goes as deep as it can before backing up. From the current node it moves to the first unseen neighbour, makes that the current node, and repeats. When a node has no unseen neighbours left, it is finished, and the search backs up to the node it came from. The path from the start to the current node is exactly the contents of the stack, or of the call stack in the recursive version.

Recording when each node is discovered and when it is finished gives DFS its power. The intervals nest: a node's interval lies inside its parent's. In an undirected graph, every edge that is not part of the DFS tree joins a node to one of its ancestors (a back edge), so any such edge reveals a cycle. Sorting nodes by finish time, latest first, gives a topological order of a directed acyclic graph, and the same timestamps drive Tarjan's algorithms for strongly connected components and articulation points.

On the Branching graph from A, DFS visits A B D E H I F C G K J L.

The iterative DFS mistake

Recursive DFS is short, but deep graphs can overflow the call stack (Python's default recursion limit is 1,000), so DFS is often written with an explicit stack. The tempting version swaps BFS's queue for a stack and changes nothing else: pop a node, then push all its unseen neighbours, marking them seen as they are pushed. That visits every node, but not in depth-first order. Marking a node when it is pushed claims it for the current node, even if a deeper path would have reached it first.

On the Branching graph, true depth-first order from A is A B D E H I F C G K J L; the shortcut gives A B D E H I F J L C G K. On 500 random graphs generated by this page, the two orders differed on 279. The difference matters whenever the algorithm relies on DFS's structure, such as back edges or finish times. Two correct iterative versions exist: push neighbours without marking them and skip a node when it is popped if it has already been visited, or store each node on the stack together with how far through its neighbour list the search has got, which is what the simulator does.

BFS and DFS compared

Breadth-first searchDepth-first search
FrontierQueueStack or recursion
OrderBy distance from the startAlong one path, then back up
TimeO(V + E)O(V + E)
MemoryThe widest layerThe deepest path
Peak frontier, Tree84
Peak frontier, Grid520
Shortest pathsYes, in unweighted graphsNo
Good atDistances, nearest things, levelsCycles, ordering, components, backtracking

Neither uses less memory in general. In a wide, shallow graph such as a balanced tree, BFS's frontier holds a whole level, about half the nodes at the bottom, while DFS holds one root-to-leaf path. In a long, thin graph, or a grid where DFS snakes back and forth, the stack can hold almost every node.

What they are used for

  • Shortest paths without weights (BFS). Fewest moves in a puzzle, fewest hops in a network, degrees of separation in a social graph. C. Y. Lee's 1961 maze-routing algorithm for connecting circuit points is BFS on a grid.
  • Crawling and garbage collection (BFS). Web crawlers explore outward from seed pages. Cheney's 1970 copying garbage collector traverses live objects breadth-first, using the copied objects themselves as the queue.
  • Cycles and ordering (DFS). Detecting cycles, ordering build steps or course prerequisites topologically, and resolving dependencies.
  • Structure (DFS). Connected components, strongly connected components, bridges and articulation points, all in linear time.
  • Backtracking (DFS). Solving puzzles, generating permutations, and searching game trees explore choices depth-first and undo them on the way back.

For weighted graphs, BFS's queue becomes a priority queue and the result is Dijkstra's algorithm; adding a heuristic gives A*.

Variants

  • Bidirectional BFS searches from both ends and stops when the frontiers meet. Each side only has to go half the distance, which in graphs that branch quickly means far fewer nodes.
  • Multi-source BFS starts with several nodes in the queue, giving each node its distance to the nearest source, such as the nearest exit or hospital.
  • 0-1 BFS handles edges of weight 0 or 1 with a double-ended queue, adding weight-0 neighbours at the front.
  • Iterative deepening DFS, analysed by Richard Korf in 1985, runs depth-limited DFS with limits 1, 2, 3 and so on. It finds shortest paths like BFS while using only DFS's memory, at the cost of repeating the shallow levels.

History

Depth-first search is older than computers: a version for solving mazes is credited to the 19th-century French mathematician Charles Pierre Trémaux. Breadth-first search was described by Konrad Zuse in 1945, in an unpublished thesis on his Plankalkül language, and reinvented by Edward F. Moore in 1959 to find the shortest path through a maze. C. Y. Lee applied it to wire routing in 1961.

Depth-first search became central to algorithm design through the work of Robert Tarjan and John Hopcroft in the early 1970s. Tarjan's 1972 paper "Depth-First Search and Linear Graph Algorithms" used DFS's discovery order to find strongly connected components and biconnected components in linear time, and Hopcroft and Tarjan applied it to further graph problems, including testing whether a graph can be drawn without crossing edges. They received the 1986 Turing Award in part for this work.

BFS and DFS questions and answers

What is the difference between BFS and DFS?

Breadth-first search (BFS) explores a graph in layers: first every neighbour of the start, then every node two edges away, and so on, using a queue. Depth-first search (DFS) follows one path as far as it can, then backs up to the most recent node with an unexplored neighbour, using a stack or recursion. Both visit every reachable node once in O(V + E) time; they differ in the order, in what each order is good for, and in how much memory they need.

When should I use BFS instead of DFS?

Use BFS when you need the shortest path in an unweighted graph, the fewest moves in a puzzle, or everything within k steps. Use DFS for problems about structure: detecting cycles, topological sorting, connected and strongly connected components, articulation points, and backtracking searches over choices.

Does BFS find the shortest path?

Yes, in an unweighted graph. BFS reaches nodes in order of their distance in edges from the start, so the first time it reaches a node is along a path with the fewest edges, and following parent pointers back gives that path. With weighted edges you need Dijkstra’s algorithm instead.

Is iterative DFS with a stack the same as recursive DFS?

Only if it is written carefully. The common shortcut, popping a node and pushing all its unseen neighbours while marking them seen, does not produce a depth-first order. On the Branching graph here, depth-first order from A is A B D E H I F C G K J L, while the shortcut gives A B D E H I F J L C G K. A correct iterative DFS either marks nodes when they are popped, or keeps each node’s position in its neighbour list on the stack, as this simulator does.

Which uses more memory, BFS or DFS?

BFS stores the frontier, which can be a whole layer of the graph: in a binary tree, about half the nodes in the last level. DFS stores the current path, so its memory grows with depth. On this page’s tree, BFS’s queue peaks at 8 nodes and DFS’s stack at 4; on the grid, a long snaking path makes DFS’s stack reach 20 while BFS’s queue peaks at 5.

What is the time complexity of BFS and DFS?

O(V + E) for a graph stored as adjacency lists: each node is taken from the queue or stack once and each edge is examined once from each end. With an adjacency matrix it is O(V²), because finding a node’s neighbours means scanning a whole row.

Further reading

Published Updated