Graphs: Breadth‐first search - rFronteddu/general_wiki GitHub Wiki
Given a graph G = (V,E) and a source vertex s, BFS explores the graph to:
- Discover all vertices reachable from s
- Computes the shortest distance from s to each reachable vertex.
- produces a BFS tree rooted at s, containing all reachable vertices.
For any reachable vertex v, the path from s to v in the BFS tree corresponds to the shortest path (minimum edges) from s to v in G. BFS works on both directed and undirected graphs.
Key Characteristics:
- BFS expands outward uniformly from the source, discovering all vertices at distance k before moving to distance k+1.
- Each vertex is assigned a color to track its status:
- White: Undiscovered.
- Gray: Discovered but not fully explored.
- Black: Fully explored.
As BFS progresses, discovered vertices and their edges are added to the BFS tree. Each vertex has at most one parent, determined when it's first discovered.
// G expressed as adjacency list
// G.p is parent/predecessor
// G.d is distance from s
// The running time is O(V) for the initialization + O(E) for adjacency exploration
BFS(G, s)
for u in G.V - {s}
u.color = WHITE
u.d = ∞
u.p = nil
s.color = GRAY
s.d = 0
s.p = nil
let q be a FIFO queue
q.add(s)
while !q.isEmpty()
u = q.poll()
for each v in G.Adj[u]
if v.color == WHITE
v.color = GRAY
v.d = u.d + 1
v.p = u
q.add(v)
u.color = BLACK
// runs in linear time relative to the number of vertices in the path printed
// since each recursive call processes one vertex at a time
printPath(G, s, v)
if v == s
print s
elseif v.p == nil
print "no path from " s " to " v "exists"
else
printPath(G, s, v.p)
print v
Shortest Path
Define the shortest-path distance $\delta(s,v)$ from s to v as the minimum number of edges in any path from vertex s to vertex v; if there is no path this distance is max. We call a shortest path any path of length $\delta(s,v)$ from s to v.
Breath-first trees
The BFS algorithm constructs a BF tree while exploring the graph. This tree corresponds to the parent (or predecessor) attributes of each vertex. For graph G = (V, E) with a source vertex s, the predecessor $G_p$ is defined as:
$$G_p = (V_p, E_p)$$
Where:
- $V_p$ = { $v \in V : v.p \neq nil$ } U {s}
- $E_p$ = { $(v.p,v) : v \in V_p$ - {s}}
The subgraph $G_p$ forms a BF tree if:
- $V_p$ consists of all vertices reachable from s
- For every vertex $v \in V_p$ $G_p$ contains a unique simple path from s to v, which is also the shortest path from s to v in G.
Since the BF tree is connected and contains no cycle, it satisfies the property that $|E_p|=|V_p| - 1$, making it a proper tree.
A proper tree is a connected, acyclic graph that has exactly n-1 edges for n vertices. In a BFS context, the predecessor subgraph forms a proper tree, meaning it includes all vertices reachable from the source and has the minimum number of edges to remain connected.