-
Notifications
You must be signed in to change notification settings - Fork 20.4k
Implement topological sort with DAG validation and cycle detection #6568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
the-yash-rajput
wants to merge
12
commits into
TheAlgorithms:master
from
the-yash-rajput:TopologicalSort
+463
−0
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
608fe18
Implement topological sort with DAG validation and cycle detection
the-yash-rajput 11ba0e3
Format Java files with clang-format
the-yash-rajput bb73f0a
Add missing newline at end of TopologicalSort class
the-yash-rajput 299974a
Merge branch 'master' into TopologicalSort
the-yash-rajput a409f33
Format Java files with clang-format
the-yash-rajput 2fe708f
Merge branch 'TopologicalSort' of github.com:the-yash-rajput/Java int...
the-yash-rajput 045c7fc
Format Java files with clang-format
the-yash-rajput b43b7e0
Add missing newline at end of TopologicalSort class
the-yash-rajput 4d0dca0
Adding build failed fixes.
the-yash-rajput ba57565
Adding build failed fixes.
the-yash-rajput 58e322b
Adding build failed fixes.
the-yash-rajput 88f2467
Adding build failed fixes.
the-yash-rajput File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package com.thealgorithms.graph; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Stack; | ||
|
||
/** | ||
* Topological Sort Algorithm | ||
* | ||
* Topological sorting of a directed graph is a linear ordering of its vertices | ||
* such that for every directed edge (u,v) from vertex u to vertex v, u comes | ||
* before v in the ordering. | ||
* | ||
* A topological sort is possible only in a directed acyclic graph (DAG). | ||
* This file contains code of finding topological sort using Depth First Search technique. | ||
*/ | ||
public final class TopologicalSort { | ||
|
||
private TopologicalSort() { | ||
throw new AssertionError("No instances."); | ||
} | ||
|
||
/** | ||
* Class that represents a directed graph and provides methods for | ||
* manipulating the graph | ||
*/ | ||
public static class Graph { | ||
private final int n; // Number of nodes | ||
private final List<List<Integer>> adj; // Adjacency list representation | ||
|
||
/** | ||
* Constructor for the Graph class | ||
* @param nodes Number of nodes in the graph | ||
*/ | ||
public Graph(int nodes) { | ||
this.n = nodes; | ||
this.adj = new ArrayList<>(nodes); | ||
for (int i = 0; i < nodes; i++) { | ||
adj.add(new ArrayList<>()); | ||
} | ||
} | ||
|
||
/** | ||
* Function that adds an edge between two nodes or vertices of graph | ||
* @param u Start node of the edge | ||
* @param v End node of the edge | ||
*/ | ||
public void addEdge(int u, int v) { | ||
adj.get(u).add(v); | ||
} | ||
|
||
/** | ||
* Get the adjacency list of the graph | ||
* @return The adjacency list | ||
*/ | ||
public List<List<Integer>> getAdjacencyList() { | ||
return adj; | ||
} | ||
|
||
/** | ||
* Get the number of nodes in the graph | ||
* @return The number of nodes | ||
*/ | ||
public int getNumNodes() { | ||
return n; | ||
} | ||
} | ||
|
||
/** | ||
* Function to perform Depth First Search on the graph | ||
* @param v Starting vertex for depth-first search | ||
* @param visited Array representing whether each node has been visited | ||
* @param recStack Array representing nodes in current recursion stack | ||
* @param graph Adjacency list of the graph | ||
* @param stack Stack containing the vertices for topological sorting | ||
* @return true if cycle is detected, false otherwise | ||
*/ | ||
private static boolean dfs(int v, boolean[] visited, boolean[] recStack, List<List<Integer>> graph, Stack<Integer> stack) { | ||
visited[v] = true; | ||
recStack[v] = true; | ||
|
||
for (int neighbour : graph.get(v)) { | ||
if (!visited[neighbour]) { | ||
if (dfs(neighbour, visited, recStack, graph, stack)) { | ||
return true; // Cycle detected | ||
} | ||
} else if (recStack[neighbour]) { | ||
return true; // Back edge found - cycle detected | ||
} | ||
} | ||
|
||
recStack[v] = false; // Remove from recursion stack | ||
stack.push(v); | ||
return false; | ||
} | ||
|
||
/** | ||
* Function to get the topological sort of the graph | ||
* @param g Graph object | ||
* @return A list containing the topological order of nodes | ||
* @throws IllegalArgumentException if cycle is detected | ||
*/ | ||
public static List<Integer> sort(Graph g) { | ||
int n = g.getNumNodes(); | ||
List<List<Integer>> adj = g.getAdjacencyList(); | ||
boolean[] visited = new boolean[n]; | ||
boolean[] recStack = new boolean[n]; | ||
Stack<Integer> stack = new Stack<>(); | ||
|
||
for (int i = 0; i < n; i++) { | ||
if (!visited[i] && dfs(i, visited, recStack, adj, stack)) { | ||
throw new IllegalArgumentException("cycle detected in graph"); | ||
} | ||
} | ||
|
||
List<Integer> ans = new ArrayList<>(); | ||
while (!stack.isEmpty()) { | ||
int elem = stack.pop(); | ||
ans.add(elem); | ||
} | ||
|
||
return ans; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.