- Graph traversal (or graph search) refers to the process of visiting all of the nodes in a graph.
- Such traversal algorithms are classified by the order in which the nodes are visited.
- Tree traversal is a special case of graph traversal where the graph is a tree.
Breadth-First Search (BFS)
- Let be a graph and be a starting node.
- The layers of the node in the graph constructed by BFS are defined as follows:
- (the set of vertices adjacent to )
- (the set of vertices adjacent to the vertices in that are not in )
- is the set of vertices at distance from .
- BFS is not only determining the nodes reachable from , but also the shortest path from to them.
- For each , layer produced by BFS consists of all nodes at distance exactly from .
- There is a path from to if and only if appears in some layer.
- BFS produces a BFS tree rooted at which is a tree .
- (the set of nodes reachable from )
- If and , then .
- (3.4) If and (a non-tree edge), then either and are in the same layer, or they are in adjacent layers.
- BFS explores the connected component in the graph containing .
- is the set of nodes reachable from , produced as the following algorithm:
- Start with
- While there exists an edge such that and , add to .
- (note: in this context, connected component refers to the set of nodes, not the subgraph induced by them)
- is the set of nodes reachable from , produced as the following algorithm:
- The layers of the node in the graph constructed by BFS are defined as follows:
Layered BFS Algorithm
- Input: A graph and a starting node .
- Output: A BFS tree rooted at .
BFS Algorithm:
Runs in O(n+m) time if the graph is represented as an adjacency list.
---
BFS(G, s):
Discovered[s]=true
for all other v, Discovered[v]=false
L[0] = {s} // layer 0
i = 0 // layer counter
T = {} // BFS tree initially empty
while L[i] != {} do
L[i+1] = {}
for each v in L[i] do
for each (v,u) in E do
if not Discovered[u] then
Discovered[u] = true
Add u to L[i+1]
Add (v,u) to T
i = i+1
Queue-based BFS Algorithm
- Input: A graph and a starting node .
- Output:
- Traversal Order: It prints the nodes in the order they are visited by BFS.
- Distance: For each node
v
reachable froms
, it finds the shortest distance froms
tov
. - Predescessor: For each node
v
reachable froms
, it finds the predecessor ofv
in the BFS tree.
BFS(G, s):
Queue = empty queue
foreach v in V:
v.visited = false
v.distance = infinity
v.parent = null
Queue.enqueue(s)
s.visited = true
s.distance = 0
while Queue is not empty:
v = Queue.dequeue()
print(v)
foreach neighbor u of v:
if u.visited == false:
u.visited = true
u.distance = v.distance + 1
u.parent = v
Queue.enqueue(u)
Depth-First Search (DFS)
DFS (Undirected)
- An edge is a tree edge if is visited for the first time when is explored. (i.e.
visited(u) = false
) - An edge is a back edge if is already visited when is explored. (i.e.
visited(u) = true
) - The tree that DFS constructs is called a DFS tree.
Algorithm 2.2 DFS(G)
Input: G = (V, E) connected undirected graph on n vertices
---
for all v ∈ V do
vistied(v) ← false
for all v ∈ V do
if not visited(v) then
DFS-Explore(G, v)
Algorithm 2.3 DFS-Explore(G, v)
---
visited(v) ← true
for all (v, u) ∈ E do
if not visited(u) then
DFS-Explore(G, u)
Stack-based DFS Algorithm
DFS Algorithm: (Stack-based)
Runnning time: O(n+m) (if the graph is represented as an adjacency list)
---
DFS(s):
Initialize S to be a stack with one element s
While S is not empty do
Pop v from S
If Explored[u] = false then
Set Explored[u] = true
For each edge (u,v) incident to u do
Push v onto S
binary tree traversal and DFS
todo which one of the bianry tree traversal algorithms (inorder, preorder, postorder) is a DFS algorithm on a binary tree?
DFS (Directed)
- A tree edge is an edge such that was first discovered by exploring .
- Back edges are those edges connecting a vertex to an ancestor in a depth-first tree. We consider self-loops, which may occur in directed graphs, as back edges.
- Forward edges are those nontree edges connecting a vertex to a proper descendant in a depth-first tree.
- Cross edges are all other edges. They can go between vertices in the same depth-first tree, as long as one vertex is not an ancestor of the other, or they can go between vertices in different depth-first trees.
DFS_visits_explore(G,v):
visited[v] = true
clock++
pre[v] = clock
for each edge (v,u) in E do
if not visited[u] then
DFS_visits_explore(G,u)
clock++
post[v] = clock