99import java .util .Set ;
1010
1111/**
12- * A class that represents the adjaceny list of a graph
12+ * A class representing the adjacency list of a directed graph. The adjacency list
13+ * maintains a mapping of vertices to their adjacent vertices.
14+ *
15+ * @param <E> the type of vertices, extending Comparable to ensure that vertices
16+ * can be compared
1317 */
1418class AdjacencyList <E extends Comparable <E >> {
1519
1620 Map <E , ArrayList <E >> adj ;
1721
22+ /**
23+ * Constructor to initialize the adjacency list.
24+ */
1825 AdjacencyList () {
19- adj = new LinkedHashMap <E , ArrayList < E > >();
26+ adj = new LinkedHashMap <>();
2027 }
2128
2229 /**
23- * This function adds an Edge to the adjaceny list
30+ * Adds a directed edge from one vertex to another in the adjacency list.
31+ * If the vertex does not exist, it will be added to the list.
2432 *
25- * @param from , the vertex the edge is from
26- * @param to, the vertex the edge is going to
33+ * @param from the starting vertex of the directed edge
34+ * @param to the destination vertex of the directed edge
2735 */
2836 void addEdge (E from , E to ) {
29- try {
30- adj .get (from ).add (to );
31- } catch (Exception E ) {
32- adj .put (from , new ArrayList <E >());
33- adj .get (from ).add (to );
37+ if (!adj .containsKey (from )) {
38+ adj .put (from , new ArrayList <>());
3439 }
40+ adj .get (from ).add (to );
3541 if (!adj .containsKey (to )) {
36- adj .put (to , new ArrayList <E >());
42+ adj .put (to , new ArrayList <>());
3743 }
3844 }
3945
4046 /**
41- * @param v, A vertex in a graph
42- * @return returns an ArrayList of all the adjacents of vertex v
47+ * Retrieves the list of adjacent vertices for a given vertex.
48+ *
49+ * @param v the vertex whose adjacent vertices are to be fetched
50+ * @return an ArrayList of adjacent vertices for vertex v
4351 */
4452 ArrayList <E > getAdjacents (E v ) {
4553 return adj .get (v );
4654 }
4755
4856 /**
49- * @return returns a set of all vertices in the graph
57+ * Retrieves the set of all vertices present in the graph.
58+ *
59+ * @return a set containing all vertices in the graph
5060 */
5161 Set <E > getVertices () {
5262 return adj .keySet ();
5363 }
5464}
5565
66+ /**
67+ * A class that performs topological sorting on a directed graph using Kahn's algorithm.
68+ *
69+ * @param <E> the type of vertices, extending Comparable to ensure that vertices
70+ * can be compared
71+ */
5672class TopologicalSort <E extends Comparable <E >> {
5773
5874 AdjacencyList <E > graph ;
5975 Map <E , Integer > inDegree ;
6076
77+ /**
78+ * Constructor to initialize the topological sorting class with a given graph.
79+ *
80+ * @param graph the directed graph represented as an adjacency list
81+ */
6182 TopologicalSort (AdjacencyList <E > graph ) {
6283 this .graph = graph ;
6384 }
6485
6586 /**
66- * Calculates the in degree of all vertices
87+ * Calculates the in-degree of all vertices in the graph. The in-degree is
88+ * the number of edges directed into a vertex.
6789 */
6890 void calculateInDegree () {
6991 inDegree = new HashMap <>();
7092 for (E vertex : graph .getVertices ()) {
71- if (!inDegree .containsKey (vertex )) {
72- inDegree .put (vertex , 0 );
73- }
93+ inDegree .putIfAbsent (vertex , 0 );
7494 for (E adjacent : graph .getAdjacents (vertex )) {
75- try {
76- inDegree .put (adjacent , inDegree .get (adjacent ) + 1 );
77- } catch (Exception e ) {
78- inDegree .put (adjacent , 1 );
79- }
95+ inDegree .put (adjacent , inDegree .getOrDefault (adjacent , 0 ) + 1 );
8096 }
8197 }
8298 }
8399
84100 /**
85- * Returns an ArrayList with vertices arranged in topological order
101+ * Returns an ArrayList containing the vertices of the graph arranged in
102+ * topological order. Topological sorting ensures that for any directed edge
103+ * (u, v), vertex u appears before vertex v in the ordering.
104+ *
105+ * @return an ArrayList of vertices in topological order
106+ * @throws IllegalStateException if the graph contains a cycle
86107 */
87108 ArrayList <E > topSortOrder () {
88109 calculateInDegree ();
89- Queue <E > q = new LinkedList <E >();
110+ Queue <E > q = new LinkedList <>();
90111
91- for (final var entry : inDegree .entrySet ()) {
112+ for (var entry : inDegree .entrySet ()) {
92113 if (entry .getValue () == 0 ) {
93114 q .add (entry .getKey ());
94115 }
95116 }
96117
97118 ArrayList <E > answer = new ArrayList <>();
119+ int processedVertices = 0 ;
98120
99121 while (!q .isEmpty ()) {
100122 E current = q .poll ();
101123 answer .add (current );
124+ processedVertices ++;
125+
102126 for (E adjacent : graph .getAdjacents (current )) {
103127 inDegree .put (adjacent , inDegree .get (adjacent ) - 1 );
104128 if (inDegree .get (adjacent ) == 0 ) {
@@ -107,12 +131,16 @@ ArrayList<E> topSortOrder() {
107131 }
108132 }
109133
134+ if (processedVertices != graph .getVertices ().size ()) {
135+ throw new IllegalStateException ("Graph contains a cycle, topological sort not possible" );
136+ }
137+
110138 return answer ;
111139 }
112140}
113141
114142/**
115- * A driver class that sorts a given graph in topological order.
143+ * A driver class that sorts a given graph in topological order using Kahn's algorithm .
116144 */
117145public final class KahnsAlgorithm {
118146 private KahnsAlgorithm () {
@@ -130,7 +158,7 @@ public static void main(String[] args) {
130158
131159 TopologicalSort <String > topSort = new TopologicalSort <>(graph );
132160
133- // Printing the order
161+ // Printing the topological order
134162 for (String s : topSort .topSortOrder ()) {
135163 System .out .print (s + " " );
136164 }
0 commit comments