• 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)

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 from s, it finds the shortest distance from s to v.
    • Predescessor: For each node v reachable from s, it finds the predecessor of v 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