Given a Directed Acyclic Graph(DAG), find any Topological Sorted order of the graph.
Topological Sorted order: It is a linear ordering of vertices such that for every directed edge u -> v, where vertex u comes before v in the ordering. There can be several topological ordering for a graph.
Example:
Input:adj[][]= [[1], [], [1], [2], [2]]
Output: [4, 3, 2, 0, 1] Explanation: By following that: for an edge u->v, u must come before v, we can obtain several topological orderings and [4, 3, 2, 0, 1] is one of them.
Input: V=5 , adj[][] = [[1], [2], [], [2, 4], []]
Output: [0, 3, 1, 4, 2] Explanation: By following that: for an edge u->v, u must come before v, we can obtain several topological orderings and [0, 3, 1, 4, 2] is one of them.
[Approach]
The idea is to perform a DFS traversal starting from every unvisited vertex (from 0 to n − 1). For each DFS call, we first explore all unvisited neighbors of the current node. Once the recursive calls for all its neighbors are complete, we start pushing these nodes into a stack while backtracking. After all vertices are processed, we pop elements from the stack one by one into a list — this gives a valid topological ordering, as each node is placed before all nodes it points to.
Illustration of the algorithm:
Below is the implementation of the above algorithm.
C++
//Driver Code Starts#include<iostream>#include<vector>#include<stack>usingnamespacestd;//Driver Code EndsvoidfindTopoSort(intnode,vector<int>&vis,vector<vector<int>>&adj,stack<int>&st){vis[node]=1;for(intit:adj[node]){if(!vis[it]){findTopoSort(it,vis,adj,st);}}// push the node after all its neighboursst.push(node);}vector<int>topoSort(vector<vector<int>>&adj){intn=adj.size();stack<int>st;vector<int>vis(n,0);for(inti=0;i<n;i++){if(!vis[i]){findTopoSort(i,vis,adj,st);}}vector<int>topo;// popping elements from stack and // pushing into the listwhile(!st.empty()){topo.push_back(st.top());st.pop();}returntopo;}//Driver Code StartsvoidaddEdge(vector<vector<int>>&adj,intu,intv){adj[u].push_back(v);}intmain(){intn=5;vector<vector<int>>adj(n);// adding edges to adjacency listaddEdge(adj,0,1);addEdge(adj,2,1);addEdge(adj,3,2);addEdge(adj,4,2);vector<int>res=topoSort(adj);for(intvertex:res)cout<<vertex<<" ";cout<<endl;}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.Stack;classSolution{//Driver Code EndsstaticvoidfindTopoSort(intnode,int[]vis,ArrayList<ArrayList<Integer>>adj,Stack<Integer>st){vis[node]=1;for(Integerit:adj.get(node)){if(vis[it]==0){findTopoSort(it,vis,adj,st);}}// Push the node after visiting // all its neighboursst.push(node);}staticArrayList<Integer>topoSort(ArrayList<ArrayList<Integer>>adj){intn=adj.size();Stack<Integer>st=newStack<>();int[]vis=newint[n];for(inti=0;i<n;i++){if(vis[i]==0){findTopoSort(i,vis,adj,st);}}ArrayList<Integer>topo=newArrayList<>();// popping elements from stack and // pushing into the listwhile(!st.isEmpty()){topo.add(st.pop());}returntopo;}//Driver Code StartsstaticvoidaddEdge(ArrayList<ArrayList<Integer>>adj,intu,intv){adj.get(u).add(v);}publicstaticvoidmain(String[]args){intn=5;ArrayList<ArrayList<Integer>>adj=newArrayList<>();for(inti=0;i<n;i++)adj.add(newArrayList<>());// adding edges to adjacency listaddEdge(adj,0,1);addEdge(adj,2,1);addEdge(adj,3,2);addEdge(adj,4,2);ArrayList<Integer>res=topoSort(adj);for(intvertex:res){System.out.print(vertex+" ");}System.out.println();}}//Driver Code Ends
Python
deffindTopoSort(node,vis,adj,stack):vis[node]=1foritinadj[node]:ifvis[it]==0:findTopoSort(it,vis,adj,stack)# push the node after all its neighboursstack.append(node)deftopoSort(adj):n=len(adj)stack=[]vis=[0]*nforiinrange(n):ifvis[i]==0:findTopoSort(i,vis,adj,stack)topo=[]# popping elements from stack and # pushing into the listwhilestack:topo.append(stack.pop())returntopo#Driver Code StartsdefaddEdge(adj,u,v):adj[u].append(v)if__name__=="__main__":n=5adj=[[]for_inrange(n)]# adding edges to adjacency listaddEdge(adj,0,1)addEdge(adj,2,1)addEdge(adj,3,2)addEdge(adj,4,2)res=topoSort(adj)print(*res)#Driver Code Ends
C#
//Driver Code StartsusingSystem;usingSystem.Collections.Generic;classGFG{//Driver Code EndsstaticvoidfindTopoSort(intnode,int[]vis,List<List<int>>adj,Stack<int>st){vis[node]=1;foreach(intitinadj[node]){if(vis[it]==0){findTopoSort(it,vis,adj,st);}}// push the node after all its neighboursst.Push(node);}staticList<int>topoSort(List<List<int>>adj){intn=adj.Count;Stack<int>st=newStack<int>();int[]vis=newint[n];for(inti=0;i<n;i++){if(vis[i]==0){findTopoSort(i,vis,adj,st);}}List<int>topo=newList<int>();// popping elements from stack and // pushing into the listwhile(st.Count>0){topo.Add(st.Pop());}returntopo;}//Driver Code StartspublicstaticvoidaddEdge(List<List<int>>adj,intu,intv){adj[u].Add(v);}publicstaticvoidMain(string[]args){intn=5;List<List<int>>adj=newList<List<int>>();for(inti=0;i<n;i++)adj.Add(newList<int>());// adding edges to adjacency listaddEdge(adj,0,1);addEdge(adj,2,1);addEdge(adj,3,2);addEdge(adj,4,2);List<int>res=topoSort(adj);foreach(intvertexinres)Console.Write(vertex+" ");Console.WriteLine();}}//Driver Code Ends
JavaScript
functionfindTopoSort(node,vis,adj,stack){vis[node]=1;for(letitofadj[node]){if(vis[it]===0){findTopoSort(it,vis,adj,stack);}}// push the node after all its neighboursstack.push(node);}functiontopoSort(adj){letn=adj.length;letstack=[];letvis=newArray(n).fill(0);for(leti=0;i<n;i++){if(vis[i]===0){findTopoSort(i,vis,adj,stack);}}lettopo=[];// popping elements from stack and // pushing into the listwhile(stack.length>0){topo.push(stack.pop());}returntopo;}//Driver Code StartsfunctionaddEdge(adj,u,v){adj[u].push(v);}// Driver codeletn=5;letadj=Array.from({length:n},()=>[]);// adding edges to adjacency listaddEdge(adj,0,1);addEdge(adj,2,1);addEdge(adj,3,2);addEdge(adj,4,2);letres=topoSort(adj);console.log(res.join(" "));//Driver Code Ends
Output
4 3 2 0 1
Time Complexity: O(V+E). We visited all the nodes, and all the neighbours of each node(i.e., all the edges). Auxiliary Space: O(V). For visited array, and for stack to store the topological order.