// A Java program to print topological sorting of a DAG importjava.io.*; importjava.util.*; // This class represents a directed graph using adjacency // list representation classGraph{ privateint V; // No. of vertices privateLinkedList<Integer> adj[]; // Adjacency List //Constructor Graph(int v) { V = v; adj =newLinkedList[v]; for (int i=0; i<v; ++i) adj[i] =newLinkedList(); } // Function to add an edge into the graph voidaddEdge(int v,int w) { adj[v].add(w); } // A recursive function used by topologicalSort voidtopologicalSortUtil(int v,boolean visited[],Stack stack) { // Mark the current node as visited. visited[v] =true; Integer i; // Recur for all the vertices adjacent to this // vertex Iterator<Integer> it = adj[v].iterator(); while (it.hasNext()) { i =it.next(); if (!visited[i]) topologicalSortUtil(i, visited, stack); } // Push current vertex to stack which stores result stack.push(newInteger(v)); } // The function to do Topological Sort. It uses // recursive topologicalSortUtil() voidtopologicalSort() { Stack stack =newStack(); // Mark all the vertices as not visited boolean visited[] =newboolean[V]; for (int i =0; i < V; i++) visited[i] =false; // Call the recursive helper function to store // Topological Sort starting from all vertices // one by one for (int i =0; i < V; i++) if (visited[i] ==false) topologicalSortUtil(i, visited, stack); // Print contents of stack while (stack.empty()==false) System.out.print(stack.pop() +" "); } // Driver method publicstaticvoidmain(String args[]) { // Create a graph given in the above diagram Graph g =newGraph(6); g.addEdge(5,2); g.addEdge(5,0); g.addEdge(4,0); g.addEdge(4,1); g.addEdge(2,3); g.addEdge(3,1); System.out.println("Following is a Topological "+"sort of the given graph"); g.topologicalSort(); } } // This code is contributed by Aakash Hasija
BFS based approach
Kahn’s algorithm for Topological Sorting (In-degree Based)
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.
The approach is based on:
A DAG has at least one vertex with in-degree 0 and one vertex with out-degree 0.
Algorithm
Steps involved in finding the topological ordering of a DAG:
Step-1: Compute in-degree (number of incoming edges) for each of the vertex present in the DAG and initialize the count of visited nodes as 0.
Step-2: Pick all the vertices with in-degree as 0 and add them into a queue (Enqueue operation)
Step-3: Remove a vertex from the queue (Dequeue operation) and then.
Increment count of visited nodes by 1.
Decrease in-degree by 1 for all its neighboring nodes.
If in-degree of a neighboring nodes is reduced to zero, then add it to the queue.
Step 5: Repeat Step 3 until the queue is empty.
Step 5 :If count of visited nodes is not equal to the number of nodes in the graph then the topological sort is not possible for the given graph.
How to find in-degree of each node?
There are 2 ways to calculate in-degree of every vertex:
Take an in-degree array which will keep track of
1)Traverse the array of edges and simply increase the counter of the destination node by 1.
for each node in Nodes
indegree[node] = 0;
for each edge(src,dest) in Edges
indegree[dest]++
Time Complexity: O(V+E)
2)Traverse the list for every node and then increment the in-degree of all the nodes connected to it by 1.
for each node in Nodes
If (list[node].size()!=0) then
for each dest in list
indegree[dest]++;
Time Complexity: The outer for loop will be executed V number of times and the inner for loop will be executed E number of times, Thus overall time complexity is O(V+E).
The overall time complexity of the algorithm is O(V+E)
Implementation
// A Java program to print topological sorting of a graph // using indegrees importjava.util.*; //Class to represent a graph classGraph{ int V;// No. of vertices //An Array of List which contains //references to the Adjacency List of //each vertex List <Integer> adj[]; publicGraph(int V)// Constructor { this.V= V; adj =newArrayList[V]; for(int i =0; i < V; i++) adj[i]=newArrayList<Integer>(); } // function to add an edge to graph publicvoidaddEdge(int u,int v) { adj[u].add(v); } // prints a Topological Sort of the complete graph publicvoidtopologicalSort() { // Create a array to store indegrees of all // vertices. Initialize all indegrees as 0. int indegree[] =newint[V]; // Traverse adjacency lists to fill indegrees of // vertices. This step takes O(V+E) time for(int i =0; i < V; i++) { ArrayList<Integer> temp = (ArrayList<Integer>) adj[i]; for(int node : temp) { indegree[node]++; } } // Create a queue and enqueue all vertices with // indegree 0 Queue<Integer> q =newLinkedList<Integer>(); for(int i =0;i < V; i++) { if(indegree[i]==0) q.add(i); } // Initialize count of visited vertices int cnt =0; // Create a vector to store result (A topological // ordering of the vertices) Vector <Integer> topOrder=newVector<Integer>(); while(!q.isEmpty()) { // Extract front of queue (or perform dequeue) // and add it to topological order int u=q.poll(); topOrder.add(u); // Iterate through all its neighbouring nodes // of dequeued node u and decrease their in-degree // by 1 for(int node : adj[u]) { // If in-degree becomes zero, add it to queue if(--indegree[node] ==0) q.add(node); } cnt++; } // Check if there was a cycle if(cnt != V) { System.out.println("There exists a cycle in the graph"); return ; } // Print topological order for(int i : topOrder) { System.out.print(i+" "); } } } // Driver program to test above functions classMain{ publicstaticvoidmain(String args[]) { // Create a graph given in the above diagram Graph g=newGraph(6); g.addEdge(5,2); g.addEdge(5,0); g.addEdge(4,0); g.addEdge(4,1); g.addEdge(2,3); g.addEdge(3,1); System.out.println("Following is a Topological Sort"); g.topologicalSort(); } }