|
2 | 2 |
|
3 | 3 | importjava.util.ArrayList;
|
4 | 4 | importjava.util.List;
|
| 5 | +importjava.util.concurrent.CopyOnWriteArrayList; |
5 | 6 |
|
6 | 7 | importcom.jwetherell.algorithms.data_structures.Graph;
|
7 | 8 |
|
|
14 | 15 | */
|
15 | 16 | publicclassTopologicalSort {
|
16 | 17 |
|
17 |
| -privateTopologicalSort() { |
18 |
| - }; |
| 18 | +privateTopologicalSort() { } |
19 | 19 |
|
| 20 | +/** |
| 21 | + * Performs a topological sort on a directed graph. Returns NULL if a cycle is detected. |
| 22 | + * |
| 23 | + * @param graph |
| 24 | + * @return Sorted List of Vertices or NULL if graph has a cycle |
| 25 | + */ |
20 | 26 | publicstaticfinalList<Graph.Vertex<Integer>> sort(Graph<Integer> graph) {
|
| 27 | +if (graph == null) |
| 28 | +thrownewIllegalArgumentException("Graph is NULL."); |
| 29 | + |
| 30 | +if (graph.getType() != Graph.TYPE.DIRECTED) |
| 31 | +thrownewIllegalArgumentException("Cannot perform a topological sort on a non-directed graph. graph type = "+graph.getType()); |
| 32 | + |
21 | 33 | List<Graph.Vertex<Integer>> sorted = newArrayList<Graph.Vertex<Integer>>();
|
22 | 34 | List<Graph.Vertex<Integer>> noOutgoing = newArrayList<Graph.Vertex<Integer>>();
|
| 35 | + |
| 36 | +List<Graph.Edge<Integer>> edges = newCopyOnWriteArrayList<Graph.Edge<Integer>>(); |
| 37 | +edges.addAll(graph.getEdges()); |
| 38 | + |
23 | 39 | for (Graph.Vertex<Integer> v : graph.getVerticies()) {
|
24 |
| -if (v.getEdges().size() == 0) { |
| 40 | +if (v.getEdges().size() == 0) |
25 | 41 | noOutgoing.add(v);
|
26 |
| - } |
27 | 42 | }
|
28 | 43 | while (noOutgoing.size() > 0) {
|
29 | 44 | Graph.Vertex<Integer> v = noOutgoing.remove(0);
|
30 | 45 | sorted.add(v);
|
31 |
| -for (Graph.Edge<Integer> e : graph.getEdges()) { |
| 46 | +for (Graph.Edge<Integer> e : edges) { |
32 | 47 | Graph.Vertex<Integer> v2 = e.getFromVertex();
|
33 | 48 | Graph.Vertex<Integer> v3 = e.getToVertex();
|
34 | 49 | if (v3.equals(v)) {
|
35 |
| -graph.getEdges().remove(e); |
| 50 | +edges.remove(e); |
36 | 51 | v2.getEdges().remove(e);
|
37 | 52 | }
|
38 | 53 | if (v2.getEdges().size() == 0)
|
39 | 54 | noOutgoing.add(v2);
|
40 | 55 | }
|
41 | 56 | }
|
42 |
| -if (graph.getEdges().size() > 0) |
43 |
| -System.out.println("cycle detected"); |
| 57 | +if (edges.size() > 0) |
| 58 | +returnnull; |
44 | 59 | returnsorted;
|
45 | 60 | }
|
46 | 61 | }
|
0 commit comments