Skip to main content

Section 34.11 Topological Sort

We now will turn out attention to a few examples of graph algorithms that build on a basic depth-first or breadth-first search to solve a particular problem. As our first example, we will look at topological sorting.
Given a directed graph like the one below, a natural desire is to find a valid ordering for the verticies. If we are going to take one class at a time, what would be a valid order to take them in?
Math 111, CS 160, CS161, CS162, CS205 are all circles (nodes). Math 111 has an arrow (edge) pointing to CS 160. CS 160 has an arrow pointing to CS 161, which has an arrow pointing to CS 162, which has an arrow pointing to CS 205.πŸ”—
Figure 34.11.1. A prerequisite chart for a Computer Science major.
Taking a directed graph and producing a valid ordering of the vertices is called topological sorting. In the example above, one valid topological sort would be MTH111 -> MTH112 -> CS160 -> CS161 -> CS162 -> CS205. But that is not the only valid topological sort. CS160 does not depend on anything and nothing depends on MTH 112, so another valid topological sort would be CS160 -> MTH111 -> CS161 -> CS162 -> CS205 -> MTH112.
Finding a valid ordering for that simple graph is not too difficult. Some simple rules of thumb get us most of the way there. Anything with no prerequisites can be taken first. Anything that is not a prerequisite for anything else can be taken last. That leaves only a few things to sort out in the middle. But what if we had a much larger graph with many vertices and edges? The graph below is not much larger, but already much harder to sort at a glance.
A graph with vertices 1 through 7. 1 points to 5 and 7. 2 points to 4. 3 points to 4. 4 points to 5 and 6. 5 points to 6.πŸ”—
Figure 34.11.2. A directed graph.
Two valid topological sorts for the graph on the left. The first is 3->2->4->1->7->5->6. The second is 1->7->2->3->4->5->6.πŸ”—
Figure 34.11.3. Two valid topological sorts.
We can do a topological sort by doing a series of depth-first searches until all vertices are visited. We will start from the first vertex and explore from there. When we finish a recursive call, we add the vertex to the front of a list of visited vertices.

Insight 34.11.1.

If we are done with recursive calls in a depth-first search, we know that we have explored all vertices reachable from that vertex and they are already in the list. So it is safe to add the vertex to the front of the list at that point.
TopologicalSort(graph):
  Set visitedSet
  List topoSortOrder
  for each vertex in graph:
    if not visitedSet.contains(vertex):
      // start a depth-first search from vertex
      doTopoSort(graph, vertex, visitedSet, topoSortOrder)

doTopoSort(graph, vertex, visitedSet, topoSortOrder):
  if visitedSet.contains(vertex):
    return
  visitedSet.add(vertex)
  for each neighbor in graph.getNeighbors(vertex):
    doTopoSort(graph, neighbor, visitedSet, topoSortOrder)
  topoSortOrder.addFront(vertex)
If you compare doTopoSort with DFS from ListingΒ 34.7.3, you’ll notice that the basic structure is the same. All we do is a little extra work to add items to the front of a list when we finish exploring them (line 15). Lines 4-7 make sure we visit every vertex in the graph by starting a depth-first search from each unvisited vertex.
Use the interactive below to explore topological sorting.

Activity 34.11.1. Topological Sort - Depth-First Search.

The animation will load a random graph and start a depth-first search from vertex 0. Step through the animation. As you do so, watch how the TopoSortOrder table is updated.
The d label on each node shows the timestep we enter that vertex. The f label shows the timestep we finish exploring that vertex. When we finish exploring a vertex, we add it to the front of the TopoSortOrder list. Thus the final list is a reverse ordering of the finish times.
Use New Graph button to generate a new random graph. (You may need to fast forward to the end before being able to create a new 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.11.1.

Which of the following is NOT a valid topological sort for FigureΒ 34.11.1?
  • CS160 -> MTH111 -> MTH112 -> CS161 -> CS162 -> CS205
  • MTH111 -> MTH112 -> CS160 -> CS161 -> CS162 -> CS205
  • MTH111 -> MTH112 -> CS160 -> CS161 -> CS205 -> CS162
  • MTH111 -> CS160 -> MTH112 -> CS161 -> CS162 -> CS205
You have attempted of activities on this page.