Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every directed edge uv, vertex u comes before v in the ordering. Topological Sorting for a graph is not possible if the graph is not a DAG.

For example, a topological sorting of the following graph is “5 4 2 3 1 0”. There can be more than one topological sorting for a graph. For example, another topological sorting of the following graph is “4 5 2 3 1 0”. The first vertex in topological sorting is always a vertex with in-degree as 0 (a vertex with no in-coming edges)

Topological Sorting vs Depth First Traversal (DFS):
In DFS, we print a vertex and then recursively call DFS for its adjacent vertices. In topological sorting, we need to print a vertex before its adjacent vertices. For example, in the given graph, the vertex ‘5’ should be printed before vertex ‘0’, but unlike DFS, the vertex ‘4’ should also be printed before vertex ‘0’. So Topological sorting is different from DFS. For example, a DFS of the shown graph is “5 2 3 1 0 4”, but it is not a topological sorting

Algorithm to find Topological Sorting:
We recommend to first see implementation of DFS here. We can modify DFS to find Topological Sorting of a graph. In DFS, we start from a vertex, we first print it and then recursively call DFS for its adjacent vertices. In topological sorting, we use a temporary stack. We don’t print the vertex immediately, we first recursively call topological sorting for all its adjacent vertices, then push it to a stack. Finally, print contents of stack. Note that a vertex is pushed to stack only when all of its adjacent vertices (and their adjacent vertices and so on) are already in stack.

Following are C++ and Java implementations of topological sorting. Please see the code for Depth First Traversal for a disconnected Graph and note the differences between the second code given there and the below code.

[ad type=”banner”]

C++ Programming:

[pastacode lang=”cpp” manual=”%2F%2F%20A%20C%2B%2B%20program%20to%20print%20topological%20sorting%20of%20a%20DAG%0A%23include%3Ciostream%3E%0A%23include%20%3Clist%3E%0A%23include%20%3Cstack%3E%0Ausing%20namespace%20std%3B%0A%20%0A%2F%2F%20Class%20to%20represent%20a%20graph%0Aclass%20Graph%0A%7B%0A%20%20%20%20int%20V%3B%20%20%20%20%2F%2F%20No.%20of%20vertices’%0A%20%0A%20%20%20%20%2F%2F%20Pointer%20to%20an%20array%20containing%20adjacency%20listsList%0A%20%20%20%20list%3Cint%3E%20*adj%3B%0A%20%0A%20%20%20%20%2F%2F%20A%20function%20used%20by%20topologicalSort%0A%20%20%20%20void%20topologicalSortUtil(int%20v%2C%20bool%20visited%5B%5D%2C%20stack%3Cint%3E%20%26Stack)%3B%0Apublic%3A%0A%20%20%20%20Graph(int%20V)%3B%20%20%20%2F%2F%20Constructor%0A%20%0A%20%20%20%20%20%2F%2F%20function%20to%20add%20an%20edge%20to%20graph%0A%20%20%20%20void%20addEdge(int%20v%2C%20int%20w)%3B%0A%20%0A%20%20%20%20%2F%2F%20prints%20a%20Topological%20Sort%20of%20the%20complete%20graph%0A%20%20%20%20void%20topologicalSort()%3B%0A%7D%3B%0A%20%0AGraph%3A%3AGraph(int%20V)%0A%7B%0A%20%20%20%20this-%3EV%20%3D%20V%3B%0A%20%20%20%20adj%20%3D%20new%20list%3Cint%3E%5BV%5D%3B%0A%7D%0A%20%0Avoid%20Graph%3A%3AaddEdge(int%20v%2C%20int%20w)%0A%7B%0A%20%20%20%20adj%5Bv%5D.push_back(w)%3B%20%2F%2F%20Add%20w%20to%20v%E2%80%99s%20list.%0A%7D%0A%20%0A%2F%2F%20A%20recursive%20function%20used%20by%20topologicalSort%0Avoid%20Graph%3A%3AtopologicalSortUtil(int%20v%2C%20bool%20visited%5B%5D%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20stack%3Cint%3E%20%26Stack)%0A%7B%0A%20%20%20%20%2F%2F%20Mark%20the%20current%20node%20as%20visited.%0A%20%20%20%20visited%5Bv%5D%20%3D%20true%3B%0A%20%0A%20%20%20%20%2F%2F%20Recur%20for%20all%20the%20vertices%20adjacent%20to%20this%20vertex%0A%20%20%20%20list%3Cint%3E%3A%3Aiterator%20i%3B%0A%20%20%20%20for%20(i%20%3D%20adj%5Bv%5D.begin()%3B%20i%20!%3D%20adj%5Bv%5D.end()%3B%20%2B%2Bi)%0A%20%20%20%20%20%20%20%20if%20(!visited%5B*i%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20topologicalSortUtil(*i%2C%20visited%2C%20Stack)%3B%0A%20%0A%20%20%20%20%2F%2F%20Push%20current%20vertex%20to%20stack%20which%20stores%20result%0A%20%20%20%20Stack.push(v)%3B%0A%7D%0A%20%0A%2F%2F%20The%20function%20to%20do%20Topological%20Sort.%20It%20uses%20recursive%20%0A%2F%2F%20topologicalSortUtil()%0Avoid%20Graph%3A%3AtopologicalSort()%0A%7B%0A%20%20%20%20stack%3Cint%3E%20Stack%3B%0A%20%0A%20%20%20%20%2F%2F%20Mark%20all%20the%20vertices%20as%20not%20visited%0A%20%20%20%20bool%20*visited%20%3D%20new%20bool%5BV%5D%3B%0A%20%20%20%20for%20(int%20i%20%3D%200%3B%20i%20%3C%20V%3B%20i%2B%2B)%0A%20%20%20%20%20%20%20%20visited%5Bi%5D%20%3D%20false%3B%0A%20%0A%20%20%20%20%2F%2F%20Call%20the%20recursive%20helper%20function%20to%20store%20Topological%0A%20%20%20%20%2F%2F%20Sort%20starting%20from%20all%20vertices%20one%20by%20one%0A%20%20%20%20for%20(int%20i%20%3D%200%3B%20i%20%3C%20V%3B%20i%2B%2B)%0A%20%20%20%20%20%20if%20(visited%5Bi%5D%20%3D%3D%20false)%0A%20%20%20%20%20%20%20%20topologicalSortUtil(i%2C%20visited%2C%20Stack)%3B%0A%20%0A%20%20%20%20%2F%2F%20Print%20contents%20of%20stack%0A%20%20%20%20while%20(Stack.empty()%20%3D%3D%20false)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20cout%20%3C%3C%20Stack.top()%20%3C%3C%20%22%20%22%3B%0A%20%20%20%20%20%20%20%20Stack.pop()%3B%0A%20%20%20%20%7D%0A%7D%0A%20%0A%2F%2F%20Driver%20program%20to%20test%20above%20functions%0Aint%20main()%0A%7B%0A%20%20%20%20%2F%2F%20Create%20a%20graph%20given%20in%20the%20above%20diagram%0A%20%20%20%20Graph%20g(6)%3B%0A%20%20%20%20g.addEdge(5%2C%202)%3B%0A%20%20%20%20g.addEdge(5%2C%200)%3B%0A%20%20%20%20g.addEdge(4%2C%200)%3B%0A%20%20%20%20g.addEdge(4%2C%201)%3B%0A%20%20%20%20g.addEdge(2%2C%203)%3B%0A%20%20%20%20g.addEdge(3%2C%201)%3B%0A%20%0A%20%20%20%20cout%20%3C%3C%20%22Following%20is%20a%20Topological%20Sort%20of%20the%20given%20graph%20%5Cn%22%3B%0A%20%20%20%20g.topologicalSort()%3B%0A%20%0A%20%20%20%20return%200%3B%0A%7D” message=”” highlight=”” provider=”manual”/]

Output:

Following is a Topological Sort of the given graph
5 4 2 3 1 0

Time Complexity: The above algorithm is simply DFS with an extra stack. So time complexity is same as DFS which is O(V+E).

Applications:
Topological Sorting is mainly used for scheduling jobs from the given dependencies among jobs. In computer science, applications of this type arise in instruction scheduling, ordering of formula cell evaluation when recomputing formula values in spreadsheets, logic synthesis, determining the order of compilation tasks to perform in makefiles, data serialization, and resolving symbol dependencies in linkers [2].

[ad type=”banner”]