The queue determines the order
The visualizer is a tree, where BFS is the Level (BFS) traversal. From root 8, it visits 8, then the next level 3 and 10, then 1, 6, and 14. Inorder, Preorder, and Postorder are depth-first traversals; they answer different ordering questions.
Press Random to build a new tree, then compare Level (BFS) with a depth-first order. Watch the highlight finish each level before moving lower. The tree view shows the traversal order; in a general graph, each node also needs a visited mark because cycles can lead back to previously seen nodes.
A graph implementation
from collections import deque
def bfs(graph, start):
seen = {start}
queue = deque([start])
order = []
while queue:
node = queue.popleft()
order.append(node)
for neighbour in graph[node]:
if neighbour not in seen:
seen.add(neighbour) # mark when enqueued
queue.append(neighbour)
return order
Marking a node when it enters the queue prevents multiple neighbours from adding it repeatedly. To recover shortest paths, store each node’s predecessor when first discovered. Because BFS discovers nodes in distance order, that predecessor chain uses the fewest edges from the source.
When BFS applies
BFS finds shortest paths by edge count in an unweighted graph, and in a graph whose edges all have equal cost. It does not find minimum-cost paths when edge weights differ; use Dijkstra’s algorithm for nonnegative weights. For adjacency lists, BFS takes O(V + E) time and O(V) extra space.
Common mistakes with Breadth First Search
- Using a stack: that produces depth-first search instead of BFS.
- Marking visited only after removal: the same node can be queued many times.
- Using BFS for unequal edge costs: fewest edges need not mean lowest cost.
- **Using
list.pop(0) in Python:** removing the first list item shifts the rest; use collections.deque.