1+ package com .thealgorithms .graph ;
2+
3+ import java .util .ArrayList ;
4+ import java .util .List ;
5+ import java .util .Stack ;
6+
7+ /**
8+ * Topological Sort Algorithm
9+ *
10+ * Topological sorting of a directed graph is a linear ordering of its vertices
11+ * such that for every directed edge (u,v) from vertex u to vertex v, u comes
12+ * before v in the ordering.
13+ *
14+ * A topological sort is possible only in a directed acyclic graph (DAG).
15+ * This file contains code of finding topological sort using Depth First Search technique.
16+ */
17+ public class TopologicalSort {
18+
19+ /**
20+ * Class that represents a directed graph and provides methods for
21+ * manipulating the graph
22+ */
23+ public static class Graph {
24+ private final int n ; // Number of nodes
25+ private final List <List <Integer >> adj ; // Adjacency list representation
26+
27+ /**
28+ * Constructor for the Graph class
29+ * @param nodes Number of nodes in the graph
30+ */
31+ public Graph (int nodes ) {
32+ this .n = nodes ;
33+ this .adj = new ArrayList <>(nodes );
34+ for (int i = 0 ; i < nodes ; i ++) {
35+ adj .add (new ArrayList <>());
36+ }
37+ }
38+
39+ /**
40+ * Function that adds an edge between two nodes or vertices of graph
41+ * @param u Start node of the edge
42+ * @param v End node of the edge
43+ */
44+ public void addEdge (int u , int v ) {
45+ adj .get (u ).add (v );
46+ }
47+
48+ /**
49+ * Get the adjacency list of the graph
50+ * @return The adjacency list
51+ */
52+ public List <List <Integer >> getAdjacencyList () {
53+ return adj ;
54+ }
55+
56+ /**
57+ * Get the number of nodes in the graph
58+ * @return The number of nodes
59+ */
60+ public int getNumNodes () {
61+ return n ;
62+ }
63+ }
64+
65+ /**
66+ * Function to perform Depth First Search on the graph
67+ * @param v Starting vertex for depth-first search
68+ * @param visited Array representing whether each node has been visited
69+ * @param recStack Array representing nodes in current recursion stack
70+ * @param graph Adjacency list of the graph
71+ * @param stack Stack containing the vertices for topological sorting
72+ * @return true if cycle is detected, false otherwise
73+ */
74+ private static boolean dfs (int v , boolean [] visited , boolean [] recStack ,
75+ List <List <Integer >> graph , Stack <Integer > stack ) {
76+ visited [v ] = true ;
77+ recStack [v ] = true ;
78+
79+ for (int neighbour : graph .get (v )) {
80+ if (!visited [neighbour ]) {
81+ if (dfs (neighbour , visited , recStack , graph , stack )) {
82+ return true ; // Cycle detected
83+ }
84+ } else if (recStack [neighbour ]) {
85+ return true ; // Back edge found - cycle detected
86+ }
87+ }
88+
89+ recStack [v ] = false ; // Remove from recursion stack
90+ stack .push (v );
91+ return false ;
92+ }
93+
94+ /**
95+ * Function to get the topological sort of the graph
96+ * @param g Graph object
97+ * @return A list containing the topological order of nodes
98+ * @throws IllegalArgumentException if cycle is detected
99+ */
100+ public static List <Integer > sort (Graph g ) {
101+ int n = g .getNumNodes ();
102+ List <List <Integer >> adj = g .getAdjacencyList ();
103+ boolean [] visited = new boolean [n ];
104+ boolean [] recStack = new boolean [n ];
105+ Stack <Integer > stack = new Stack <>();
106+
107+ for (int i = 0 ; i < n ; i ++) {
108+ if (!visited [i ]) {
109+ if (dfs (i , visited , recStack , adj , stack )) {
110+ throw new IllegalArgumentException ("cycle detected in graph" );
111+ }
112+ }
113+ }
114+
115+ List <Integer > ans = new ArrayList <>();
116+ while (!stack .isEmpty ()) {
117+ int elem = stack .pop ();
118+ ans .add (elem );
119+ }
120+
121+ return ans ;
122+ }
123+
124+ }
0 commit comments