Skip to main content

Section 34.12 Cycle Detection

Another algorithm that can be build on top of depth-first search is a “cycle detection”. A cycle in a graph is a path that starts and ends at the same vertex. For example, in the graph below, we can start at 1 and navigate through the path 1 -> 2 -> 6 -> 5 -> 1 back to vertex 1.
Graph where 1 connects to 2; 2 connects to 6; 6 connects to 5; 5 connects to 1
Figure 34.12.1. A cycle within a graph.
We can detect a cycle in a graph by doing a series of depth-first searches. We will start from the first vertex and explore from there. As we recurse into a particular vertex, we mark it as “on the stack”. When we finish a recursive call, we unmark it as “on the stack”. If we ever encounter a vertex that is already on the stack, we have found a cycle.
When this first depth-first search is complete, we will start a new depth-first search from the first vertex that was not yet visited. We continue this process until all vertices have been visited.
DetectCycle(graph):
  Set visitedSet
  for each vertex in graph:
    if not visitedSet.contains(vertex):
      // start a depth-first search from vertex
      Set onStack
      if doDFSCycle(graph, vertex, visitedSet, onStack):
        return true  // found a cycle
  return false  // no cycle found

doDFSCycle(graph, vertex, visitedSet, onStack):
  if onStack.contains(vertex):
    return true  // found a cycle
  if visitedSet.contains(vertex):
    return false  // already visited, but not on the current path
  visitedSet.add(vertex)
  onStack.add(vertex)    // this is on the path we are currently exploring
  for each neighbor in graph.getNeighbors(vertex):
    if doDFSCycle(graph, neighbor, visitedSet, onStack):
      return true  // found a cycle through this neighbor
  onStack.remove(vertex) // done exploring through this vertex
  return false
Again, doDFSCycle looks very similar to the base DFS algorithm from Listing 34.7.3. The key differences this time are:
  • We keep track of what is “on the stack” in addition to what is “visited”.
  • We return true when we detect a cycle and false if we fully explore a given vertex without finding a cycle.
Use the interactive below to explore cycle detection.

Activity 34.12.1. Cycle Detection - Depth-First Search.

The animation will load a specific graph and start a depth-first search from vertex 0. Step through the animation. As you do so, note how the OnStack tables is updated.
Fast forward to the end of the animation and then click New Graph button to generate a new random graph.

Instructions.

When the > button is highlighted, an animation is prepared to run. Use the Step button to step through the animation one step at a time.
When no animation is in progress, you can use the data controls to start a new animation.
You can click and drag on the animation area to pan around. Use the Ctrl + mouse wheel (or touchpad scroll gesture) while over the animation area to zoom in and out.
  • Core Controls.
    • << : Skip to the beginning of the animation.
    • < : Step backwards one step in the animation.
    • > : Step forward one step in the animation.
    • >> : Skip to the end of the animation.
    • Auto Step Speed Set to anything other than off to automatically step through the animation at the selected speed.
    • Zoom Set the zoom level. You can also use Ctrl + Mouse Wheel to zoom in and out.
  • Graph Controls.
    • New Graph Randomly generate a new graph with the same settings.
    • Directed Graph Randomly generate a new directed graph.
    • Undirected Graph Randomly generate a new undirected graph.
    • Small Graph Randomly generate a graph with 8 vertices.
    • Large Graph Randomly generate a graph with 19 vertices.
    • Logical Representation Display current graph’s logical representation.
    • Adjacency List Representation Display current graph’s adjacency list representation.
    • Adjacency Matrix Representation Display current graph’s adjacency matrix representation.

Checkpoint 34.12.1.

What situation indicates a cycle has been found in the cycle detection algorithm?
  • A vertex is encountered that is already on the current path being explored
  • A vertex is encountered that has no neighbors
  • A vertex is encountered that has already been explored in a previous depth-first search
You have attempted of activities on this page.