Given a Directed Acyclic Graph (DAG), print all its topological orderings.

A Topological ordering of a directed graph G is a linear ordering of the nodes as v1, v2 , … , vn such that all edges point forward: for every edge (vi, vj), we have i < j. Moreover, the first node in a topological ordering must have no edge coming into it. Analogously, the last node must be one that has no edge leaving it. Topological order is only possible when the graph has no directed cycles, i.e. if the graph is DAG.

 
For example, consider the following graph:

Kahn’s Topological Sort Algorithm

The above graph has many valid topological ordering of vertices like,

  7   5   3   1   4   2   0   6
  7   5   1   2   3   4   0   6
  5   7   3   1   0   2   6   4
  3   5   7   0   1   2   6   4
  5   7   3   0   1   4   6   2
  7   5   1   3   4   0   6   2
  5   7   1   2   3   0   6   4
  3   7   0   5   1   4   2   6
 
… and many more

Note that for every directed edge u —> v, u comes before v in the ordering. For example, the pictorial representation of the topological order {7, 5, 3, 1, 4, 2, 0, 6} is:

 
Kahn’s Topological Sort Algorithm

 
In the previous post, we have seen how to print the topological order of a graph using the Depth–first search (DFS) algorithm. We have also seen Kahn’s topological sort algorithm, which provides an efficient way to print the topological order. In this post, we will see how to print all possible topological orderings of a DAG.

Practice this problem

The idea remains similar to Kahn’s topological sort, where we find vertices with no incoming edges and removing all outgoing edges from these vertices. We build all possible orderings from left to right, where the vertices with in-degree zero become candidates for the next vertex. We can do this using backtracking, where the graph state is restored after processing the selected vertex.

The algorithm can be implemented as follows in C++, Java, and Python:

C++


Download  Run Code

Java


Download  Run Code

Python


Download  Run Code

Output:
 
[3, 5, 7, 0, 1, 2, 4, 6]
[3, 5, 7, 0, 1, 2, 6, 4]
[3, 5, 7, 0, 1, 4, 2, 6]
[3, 5, 7, 0, 1, 4, 6, 2]
[3, 5, 7, 0, 1, 6, 2, 4]
[3, 5, 7, 0, 1, 6, 4, 2]
[3, 5, 7, 1, 0, 2, 4, 6]
[3, 5, 7, 1, 0, 2, 6, 4]

The time complexity of the above solution is exponential and requires additional space for the recursion (call stack).