22
33import java .util .ArrayList ;
44import java .util .List ;
5- import java .util .concurrent .CopyOnWriteArrayList ;
65
76import com .jwetherell .algorithms .data_structures .Graph ;
87
@@ -20,6 +19,8 @@ private TopologicalSort() { }
2019 /**
2120 * Performs a topological sort on a directed graph. Returns NULL if a cycle is detected.
2221 *
22+ * Note: This should not change the state of the graph parameter.
23+ *
2324 * @param graph
2425 * @return Sorted List of Vertices or NULL if graph has a cycle
2526 */
@@ -30,28 +31,35 @@ public static final List<Graph.Vertex<Integer>> sort(Graph<Integer> graph) {
3031 if (graph .getType () != Graph .TYPE .DIRECTED )
3132 throw new IllegalArgumentException ("Cannot perform a topological sort on a non-directed graph. graph type = " +graph .getType ());
3233
33- List <Graph .Vertex <Integer >> sorted = new ArrayList <Graph .Vertex <Integer >>();
34- List <Graph .Vertex <Integer >> noOutgoing = new ArrayList <Graph .Vertex <Integer >>();
34+ // clone to prevent changes the graph parameter's state
35+ final Graph <Integer > clone = new Graph <Integer >(graph );
36+ final List <Graph .Vertex <Integer >> sorted = new ArrayList <Graph .Vertex <Integer >>();
37+ final List <Graph .Vertex <Integer >> noOutgoing = new ArrayList <Graph .Vertex <Integer >>();
3538
36- List <Graph .Edge <Integer >> edges = new CopyOnWriteArrayList <Graph .Edge <Integer >>();
37- edges .addAll (graph .getEdges ());
39+ final List <Graph .Edge <Integer >> edges = new ArrayList <Graph .Edge <Integer >>();
40+ edges .addAll (clone .getEdges ());
3841
39- for (Graph .Vertex <Integer > v : graph .getVerticies ()) {
42+ for (Graph .Vertex <Integer > v : clone .getVerticies ()) {
4043 if (v .getEdges ().size () == 0 )
4144 noOutgoing .add (v );
4245 }
4346 while (noOutgoing .size () > 0 ) {
44- Graph .Vertex <Integer > v = noOutgoing .remove (0 );
47+ final Graph .Vertex <Integer > v = noOutgoing .remove (0 );
4548 sorted .add (v );
46- for (Graph .Edge <Integer > e : edges ) {
47- Graph .Vertex <Integer > v2 = e .getFromVertex ();
48- Graph .Vertex <Integer > v3 = e .getToVertex ();
49- if (v3 .equals (v )) {
49+
50+ int i = 0 ;
51+ while (i < edges .size ()) {
52+ final Graph .Edge <Integer > e = edges .get (i );
53+ final Graph .Vertex <Integer > from = e .getFromVertex ();
54+ final Graph .Vertex <Integer > to = e .getToVertex ();
55+ if (to .equals (v )) {
5056 edges .remove (e );
51- v2 .getEdges ().remove (e );
57+ from .getEdges ().remove (e );
58+ } else {
59+ i ++;
5260 }
53- if (v2 .getEdges ().size () == 0 )
54- noOutgoing .add (v2 );
61+ if (from .getEdges ().size () == 0 )
62+ noOutgoing .add (from );
5563 }
5664 }
5765 if (edges .size () > 0 )
0 commit comments