It is an ordering of vertices in a directed acyclic graph in which each node comes before all the nodes to which it has outgoing edges
Topological sort for this graph will be : A, C, E, B, D
We first find a vertex which has no incoming edge (Indegree = 0)
Remove A, reduce the indegree of all its neighbors
The next vertex in this sort the one with indegree 0
Indegree
Number of inward directed graph edges for a given vertex
If there were no vertices with 0 indegree, then there would have been no topological sort
A = 0
B = 2
C = 1
E = 1
D = 2
Complexity
Running time for topological sort is O(V + E)
Each edge and every vertex visited once
Implementation
Indegree of adjacency list
public int getIndegree(int v) {
if (v < 0 || v >= numVertices) {
throw new IllegalArgumentException("Vertex number is not valid");
}
int indegree = 0;
for (int i = 0; i < numVertices; i++) {
if (getAdjacentVertices(i).contains(v)) {
indegree++;
}
}
return indegree;
}
override
public int getIndegree(int v) {
if (v < 0 || v >= numVertices) {
throw new IllegalArgumentException("Vertex number is not valid");
}
int indegree = 0;
for (int i = 0; i < getNumVertices(); i++) {
if (getAdjacentMatrix[i][v] != 0) {
indegree++;
}
}
return indegree;
}
public static List<Integer> sort(Graph graph) {
LinkedList<Integer> queue = new LinkedList<>();
Map<Integer, Integer> indegreeMap = new HashMap<>();
for (int vertex = 0; vertex < graph.getNumVertices(); vertex++) {
int indegree = graph.getIndegree(vertex);
indegreeMap.put(vertex, indegree);
if (indegree == 0) {
queue.add(vertex);
}
}
List<Integer> sortedList = new ArrayList<>();
while (!queue.isEmpty()) {
int vertex = queue.pollLast();
sortedList.add(vertex);
List<Integer> adjancentVertices = graph.getAdjancentVertices(vertex);
for (int adjancentVertex : adjancentVertices) {
int updatedIndegree = indegreeMap.get(adjancentVertex) - 1;
indegreeMap.remove(adjancentVertex);
indegreeMap.put(adjancentVertex, updatedIndegree);
if (updatedIndegree == 0) {
queue.add(adjancentVertex);
}
}
}
if (sortedList.size() != graph.getNumVertices()) {
throw new RuntimeException("Vertex number is not valid");
}
return sortedList;
}
Student schedule
We have 2 lists
List of courses
List od pre-reqs for each course
Pre-reqs are edges from one course to another - it is a relationship
All nodes with indegree = 0 are potential courses the student could start with
There are many schedule possible
public static List<String> order(List<String> courseList, Map<String, List<String>> prereqs) {
Graph courseGraph = new AdjancentMatrixGraph(courseList.size(), Graph.GraphType.DIRECTED);
Map<String, Integer> courseMap = new HashMap<>();
Map<Integer, String> idCourseMap = new HashMap<>();
for (int i = 0; i < courseList.size(); i++) {
courseMap.put(courseList.get(i), i);
idCourseMap.put(i, courseList.get(i));
}
for (Map.Entry<String, List<String>> prereq : prereq.entrySet()) {
for (String course : prereq.getValue()) {
courseGraph.addEdge(courseMap.get(prereq.getKey()),
courseMap.get(course));
}
}
List<Integer> courseIdList = TopologicalSort(courseGraph);
List<Integer> courseScheduleList = new ArrayList<>();
for (int courseId : courseIdList) {
courseScheduleList.add(idCourseMap.get(courseId));
}
return courseScheduleList;
}