Skip to content

Commit ba5139d

Browse files
fix: Complete TopologicalSortDFS with all tests and Checkstyle fixes
- Fixed all 30 Checkstyle violations - Removed wildcard imports - Removed all trailing whitespace - Added newline at end of files - Added comprehensive test suite with 11 test cases - Tests cover: basic DAG, complex DAG, cycles, self-loops, disconnected graphs, edge cases
1 parent 1958212 commit ba5139d

File tree

2 files changed

+184
-129
lines changed

2 files changed

+184
-129
lines changed
Lines changed: 48 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
package 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

Comments
 (0)