11package com .thealgorithms .graphs ;
22
3- import java .util .*;
3+ import java .util .ArrayList ;
4+ import java .util .List ;
5+ import java .util .Stack ;
46
57/**
6- * Topological Sorting using Depth- First Search (DFS)
7- *
8- * Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering
9- * of vertices such that for every directed edge u -> v, vertex u comes before v.
10- *
11- * Time Complexity: O(V + E)
12- * Space Complexity: O(V)
13- *
14- * @author gowtham1412-p
8+ * Topological Sorting using Depth First Search (DFS)
9+ * Topological sorting is a linear ordering of vertices in a Directed Acyclic Graph (DAG)
10+ * such that for every directed edge (u, v), vertex u comes before v in the ordering.
11+ *
12+ * Time Complexity: O(V + E) where V is vertices and E is edges
13+ * Space Complexity: O(V) for recursion stack and visited array
14+ *
15+ * @author Gowtham
16+ * @see <a href="https://en.wikipedia.org/wiki/Topological_sorting">Topological Sorting</a>
1517 */
16- public class TopologicalSortDFS {
17-
18- private int vertices ;
19- private List <List <Integer >> adjList ;
20-
18+ public final class TopologicalSortDFS {
19+ private final int vertices ;
20+ private final List <List <Integer >> adjList ;
21+
2122 /**
2223 * Constructor to initialize the graph
23- *
24+ *
2425 * @param vertices Number of vertices in the graph
2526 */
2627 public TopologicalSortDFS (int vertices ) {
@@ -30,71 +31,57 @@ public TopologicalSortDFS(int vertices) {
3031 adjList .add (new ArrayList <>());
3132 }
3233 }
33-
34+
3435 /**
35- * Add a directed edge to the graph
36- *
37- * @param source Source vertex
38- * @param destination Destination vertex
36+ * Add a directed edge from source to destination
37+ *
38+ * @param src Source vertex
39+ * @param dest Destination vertex
3940 */
40- public void addEdge (int source , int destination ) {
41- if (source < 0 || source >= vertices || destination < 0 || destination >= vertices ) {
42- throw new IllegalArgumentException ("Invalid vertex" );
43- }
44- adjList .get (source ).add (destination );
41+ public void addEdge (int src , int dest ) {
42+ adjList .get (src ).add (dest );
4543 }
46-
44+
4745 /**
48- * Performs topological sort using DFS
49- *
46+ * Perform topological sort on the graph
47+ *
5048 * @return List of vertices in topological order
5149 * @throws IllegalArgumentException if graph contains a cycle
5250 */
5351 public List <Integer > topologicalSort () {
54- boolean [] visited = new boolean [vertices ];
55- boolean [] recursionStack = new boolean [vertices ];
56- Stack <Integer > stack = new Stack <>();
57-
58- // Check for cycles and perform DFS
59- for (int i = 0 ; i < vertices ; i ++) {
60- if (!visited [i ]) {
61- if (hasCycleDFS (i , visited , recursionStack )) {
62- throw new IllegalArgumentException ("Graph contains a cycle. Topological sort not possible." );
63- }
64- }
52+ if (!isDAG ()) {
53+ throw new IllegalArgumentException ("Graph contains a cycle. Topological sort is not possible." );
6554 }
66-
67- // Reset visited for actual topological sort
68- Arrays .fill (visited , false );
69-
70- // Perform DFS to get topological order
55+
56+ Stack <Integer > stack = new Stack <>();
57+ boolean [] visited = new boolean [vertices ];
58+
7159 for (int i = 0 ; i < vertices ; i ++) {
7260 if (!visited [i ]) {
7361 topologicalSortDFS (i , visited , stack );
7462 }
7563 }
76-
77- // Convert stack to list
64+
7865 List <Integer > result = new ArrayList <>();
7966 while (!stack .isEmpty ()) {
8067 result .add (stack .pop ());
8168 }
82-
69+
8370 return result ;
8471 }
85-
72+
8673 /**
8774 * DFS helper method to detect cycles
88- *
75+ *
8976 * @param vertex Current vertex
9077 * @param visited Visited array
9178 * @param recursionStack Recursion stack to detect back edges
92- * @return true if cycle exists , false otherwise
79+ * @return true if cycle is detected , false otherwise
9380 */
9481 private boolean hasCycleDFS (int vertex , boolean [] visited , boolean [] recursionStack ) {
9582 visited [vertex ] = true ;
9683 recursionStack [vertex ] = true ;
97-
84+
9885 for (int neighbor : adjList .get (vertex )) {
9986 if (!visited [neighbor ]) {
10087 if (hasCycleDFS (neighbor , visited , recursionStack )) {
@@ -104,39 +91,39 @@ private boolean hasCycleDFS(int vertex, boolean[] visited, boolean[] recursionSt
10491 return true ; // Back edge found - cycle detected
10592 }
10693 }
107-
94+
10895 recursionStack [vertex ] = false ;
10996 return false ;
11097 }
111-
98+
11299 /**
113100 * DFS helper method for topological sort
114- *
101+ *
115102 * @param vertex Current vertex
116103 * @param visited Visited array
117104 * @param stack Stack to store topological order
118105 */
119106 private void topologicalSortDFS (int vertex , boolean [] visited , Stack <Integer > stack ) {
120107 visited [vertex ] = true ;
121-
108+
122109 for (int neighbor : adjList .get (vertex )) {
123110 if (!visited [neighbor ]) {
124111 topologicalSortDFS (neighbor , visited , stack );
125112 }
126113 }
127-
114+
128115 stack .push (vertex );
129116 }
130-
117+
131118 /**
132119 * Check if the graph is a DAG (Directed Acyclic Graph)
133- *
120+ *
134121 * @return true if graph is DAG, false otherwise
135122 */
136123 public boolean isDAG () {
137124 boolean [] visited = new boolean [vertices ];
138125 boolean [] recursionStack = new boolean [vertices ];
139-
126+
140127 for (int i = 0 ; i < vertices ; i ++) {
141128 if (!visited [i ]) {
142129 if (hasCycleDFS (i , visited , recursionStack )) {
@@ -146,4 +133,4 @@ public boolean isDAG() {
146133 }
147134 return true ;
148135 }
149- }
136+ }
0 commit comments