Skip to main content
Ctrl+K
Logo image

Needful Things

  • CSC 212: Data Structures & Algorithms
  • Tips for Success
  • FAQs

Problem Solving & Programming

  • Basics
    • Problem Solving
    • Expressions
    • Data Types
    • Operators
  • Main & CLAs
  • Functions
  • Controls
    • Conditionals
    • Iteration Statements
    • Jump Statements
  • Collections
    • Array
  • Classes
    • Object-Oriented Programming
    • Inheritance
    • Polymorphism
  • File Handling
  • Exceptions & Errors

Data Structures

  • Overview
  • Linear Structures
    • Dynamic Arrays
    • Linked Lists
    • Stacks
    • Queues
    • Priority Queues
  • Non-Linear Structures
    • Sets
    • Maps
    • Trees
    • Heaps
    • Binary Search Trees
    • 2-3 Trees
    • Left-Leaning Red-Black Trees
    • Hash Tables
    • Graphs
    • Graphs : Depth-First Search
    • Graphs : Breadth-First Search

Algorithms

  • Analysis
    • Analysis of Algorithms
    • Computational Cost
    • Big-O
  • Searching & Sorting
    • Recursive Algorithms (Analysis)
    • Recurrences
    • Search Algorithms
    • Basic Sorts (Analysis)
    • Mergesort
    • Quicksort
    • Heapsort
    • Timsort
    • Introsort
  • Greedy Algorithms

Miscellaneous

  • Development Environments
    • C++
    • Python
  • Learn C++
  • C++ Syntax Cheat Sheet
  • MTH 180 Concepts
  • OpenDSA
    • Logarithms
    • Summations
    • Recurrence Relations
    • Mathematical Proof Techniques
  • Submission Notes
  • Official GitHub Training Manual
  • Additional Resources
  • Repository
  • Open issue
  • .md

Graphs : Depth-First Search

Contents

  • DFS
  • Path Finding
  • Undirected Graphs

Graphs : Depth-First Search#

TL;DR

Depth-first search (DFS) is a graph traversal algorithm that visits all the vertices in a graph by exploring as far as possible along each branch before backtracking. DFS starts at a specified vertex (the starting vertex) and then follows one of its edges to an adjacent vertex. It then recursively applies the same process to the adjacent vertex, and continues until it reaches a dead end (i.e., a vertex with no unvisited adjacent vertices). It then backtracks to the most recently visited vertex with unvisited adjacent vertices, and repeats the process until all vertices have been visited.

DFS can be used to perform a variety of operations on a graph, such as finding a path between two vertices, checking whether the graph is connected, and identifying cycles in the graph. DFS can also be modified to search for solutions in a problem space, such as finding the shortest path between two points in a maze.

DFS can be implemented using either a recursive or iterative approach. The recursive approach uses a function call stack to keep track of the visited vertices and backtrack when necessary. The iterative approach uses a stack data structure to keep track of the visited vertices and their adjacent vertices.

Overall, DFS is an important algorithm in graph theory and is widely used in many applications, such as network analysis, data mining, and artificial intelligence.

Additional Resources

DFS#

Problem#

Given a digraph \(G\) and vertex \(s\), find all the vertices reachable from \(s\)

../../_images/19_07.png
https://media.geeksforgeeks.org/wp-content/uploads/20200507074112/ezgif.com-gif-maker61.gif
Goal#

Systemically traverse a digraph

void Graph::dfs( Vertex v )
{
  v.visited = true;
  for each Vertex w adjacent to v
    if( !w.visited )
      dfs( w );
}
Typical applications#

Reachability: finding all vertices reachable from a given vertex
Path finding: find directed path from one vertex to another

To visit vertex \(v\): #

Mark vertex \(v\)
Recursively visit all unmarked vertices adjacent from \(v\)

https://he-s3.s3.amazonaws.com/media/uploads/9fa1119.jpg

Fig. 75 directed dfs#

Proposition#

DFS marks all vertices reachable from \(s\) in \(\Theta(E+V)\) time in the worst case

Proof#

Initializing an array of length \(v\) takes \(\Theta(V)\) time
Each vertex is visited at most once
Visiting a vertex takes time proportional to its outdegree:

\[outdegree(v_0) + outdegree(v_1) + outdegree(v_2) + \dots = E\]
\[in\ worst\ case,\ all\ V\ vertices\ reachable\ from\ s\]
Note#

If all vertices are reachable from \(s\), then \(E \ge V - 1\), so \(V\) is a lower-order term

Program control-flow analysis

Every program is a digraph#

Vertex = basic block of instructions (straight-line program)
Edge = jump

Dead-code elimination#

Find (and remove) unreachable code

Infinite-loop detection#

Determine whether exit is unreachable

../../_images/19_12.png

Mark-sweep garbage collection

Every program is a digraph#

Vertex = basic block of instructions (straight-line program) Edge = jump

Roots#

Objects known to be directly accessible by a program (eg stack frame)

Reachable objects#

Objects indirectly accessible by program (starting at a root and following a chain of pointers)

Memory cost#

Uses 1 extra mark bit per object (plus DFS function-call stack)

../../_images/19_13.png

Path Finding#

Goal#

DFS determines which vertices are reachable from s. How to reconstruct paths?

Solution#

Use parent-link representation

../../_images/19_10.png

Fig. 76 reachable from \(0\)#

../../_images/19_14.png

Fig. 77 parent-link representation of paths from vertex \(0\)#

Parent-link representation of paths from \(s\)#

Maintain an integer array \(edgeTo[]\)
Interpretation: \(edgeTo[v]\) is the next-to-last vertex on a path from \(s\) to \(v\)
To reconstruct path from \(s\) to \(v\), trace \(edgeTo[]\) backward from \(s\) to \(v\) (and reverse)

../../_images/19_15.png

Fig. 78 reachable from \(0\)#

../../_images/19_16.png

Fig. 79 parent-link representation of paths from vertex \(0\)#

public Iterable<Integer> pathTo(int v) {
  if (!marked[v]) return null; 
  Stack<Integer> path = new Stack<>(); 
  for (int x = v; x != s; x = edgeTo[x]) 
    path.push(x); 
  path.push(s); 
  return path; 
}

Undirected Graphs#

Problem#

Implement flood fill (Photoshop magic wand)

https://static.wixstatic.com/media/bb1bd6_591167b0be9940758124b35badf1da3a~mv2.gif

Fig. 80 magic wand tool#

Problem#

Given an undirected graph \(G\) and vertex \(s\), find all vertices connected to \(s\)

Solution#

Treat undirected graph as a digraph, replacing each edge with two antiparallel edges

DFS (to visit a vertex v)
------------------------
Mark vertex v.
Recursively visit all unmarked
    vertices w adjacent to v
Typical applications#

Find all vertices connected to a given vertex Find a path between two vertices

To visit vertex \(v\): #

Mark vertex \(v\)
Recursively visit all unmarked vertices adjacent from \(v\)

image
../../_images/19_19.png

Fig. 81 vertices connected to \(0\) (and associated paths)#

image
../../_images/19_20.png
Tree traversal#

Many ways in a binary tree

stack/recursion #
\[\begin{split}\begin{align} Inorder & \ \ \ \ \ \{ A, C, E, H, M, R, S, X \} \\ Preorder & \ \ \ \ \ \{ S, E, A, C, R, H, M, X \}\\ Postorder & \ \ \ \ \ \{ C, A, M, H, R, E, X, S \} \\ \end{align}\end{split}\]
queue #
\[Level-order \ \ \ \ \ \{ S, E, X, A, R, C, H, M \} \]
../../_images/19_21.png

Fig. 82 parent-link representation of paths from vertex \(0\)#

Graph search#

Many ways to explore a graph

  • DFS preorder: vertices in order of calls to \(dfs(G,v)\)

  • DFS postorder: vertices in order of return calls from \(dfs(G,v)\)

  • Breadth-first: vertices in increasing order of distance from \(s\)

previous

Graphs

next

Graphs : Breadth-First Search

Contents
  • DFS
  • Path Finding
  • Undirected Graphs

By Professor Jonathan Schrader

© Copyright 2023.

Materials herein are a compilation under guise of 'Fair Use for Education'.
All rights reserved by their intellectual property owners, respectfully.