9
9
import java .util .Set ;
10
10
11
11
/**
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
13
17
*/
14
18
class AdjacencyList <E extends Comparable <E >> {
15
19
16
20
Map <E , ArrayList <E >> adj ;
17
21
22
+ /**
23
+ * Constructor to initialize the adjacency list.
24
+ */
18
25
AdjacencyList () {
19
- adj = new LinkedHashMap <E , ArrayList < E > >();
26
+ adj = new LinkedHashMap <>();
20
27
}
21
28
22
29
/**
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.
24
32
*
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
27
35
*/
28
36
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 <>());
34
39
}
40
+ adj .get (from ).add (to );
35
41
if (!adj .containsKey (to )) {
36
- adj .put (to , new ArrayList <E >());
42
+ adj .put (to , new ArrayList <>());
37
43
}
38
44
}
39
45
40
46
/**
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
43
51
*/
44
52
ArrayList <E > getAdjacents (E v ) {
45
53
return adj .get (v );
46
54
}
47
55
48
56
/**
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
50
60
*/
51
61
Set <E > getVertices () {
52
62
return adj .keySet ();
53
63
}
54
64
}
55
65
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
+ */
56
72
class TopologicalSort <E extends Comparable <E >> {
57
73
58
74
AdjacencyList <E > graph ;
59
75
Map <E , Integer > inDegree ;
60
76
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
+ */
61
82
TopologicalSort (AdjacencyList <E > graph ) {
62
83
this .graph = graph ;
63
84
}
64
85
65
86
/**
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.
67
89
*/
68
90
void calculateInDegree () {
69
91
inDegree = new HashMap <>();
70
92
for (E vertex : graph .getVertices ()) {
71
- if (!inDegree .containsKey (vertex )) {
72
- inDegree .put (vertex , 0 );
73
- }
93
+ inDegree .putIfAbsent (vertex , 0 );
74
94
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 );
80
96
}
81
97
}
82
98
}
83
99
84
100
/**
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
86
107
*/
87
108
ArrayList <E > topSortOrder () {
88
109
calculateInDegree ();
89
- Queue <E > q = new LinkedList <E >();
110
+ Queue <E > q = new LinkedList <>();
90
111
91
- for (final var entry : inDegree .entrySet ()) {
112
+ for (var entry : inDegree .entrySet ()) {
92
113
if (entry .getValue () == 0 ) {
93
114
q .add (entry .getKey ());
94
115
}
95
116
}
96
117
97
118
ArrayList <E > answer = new ArrayList <>();
119
+ int processedVertices = 0 ;
98
120
99
121
while (!q .isEmpty ()) {
100
122
E current = q .poll ();
101
123
answer .add (current );
124
+ processedVertices ++;
125
+
102
126
for (E adjacent : graph .getAdjacents (current )) {
103
127
inDegree .put (adjacent , inDegree .get (adjacent ) - 1 );
104
128
if (inDegree .get (adjacent ) == 0 ) {
@@ -107,12 +131,16 @@ ArrayList<E> topSortOrder() {
107
131
}
108
132
}
109
133
134
+ if (processedVertices != graph .getVertices ().size ()) {
135
+ throw new IllegalStateException ("Graph contains a cycle, topological sort not possible" );
136
+ }
137
+
110
138
return answer ;
111
139
}
112
140
}
113
141
114
142
/**
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 .
116
144
*/
117
145
public final class KahnsAlgorithm {
118
146
private KahnsAlgorithm () {
@@ -130,7 +158,7 @@ public static void main(String[] args) {
130
158
131
159
TopologicalSort <String > topSort = new TopologicalSort <>(graph );
132
160
133
- // Printing the order
161
+ // Printing the topological order
134
162
for (String s : topSort .topSortOrder ()) {
135
163
System .out .print (s + " " );
136
164
}
0 commit comments