There are two common ways
1.kahn algorithm
2. The depth-first post-order based on inverse
We need to have in the acyclic graph, or dependencies of order may cause problems
If the file ac bc cc dc dependencies between them is
a file is dependent on file b, b c document file is dependent, b d document file is dependent on
it which files to be compiled? Is the most dependent of that file (a or d) should be first compiled. How to get the correct order of compilation?
a.c -> b.c -> c.c
d.c ->
1.kahn
// topological sorting // acyclic directed graph is a topological sort prerequisite // the topological sort, the vertex node depends precursor must have first appeared in front of him again (such a sequence is called topology sequence) // long as the above condition is satisfied sorting output sequence are topology (FIG therefore tend to have a plurality of topological order) (this process is called topological Sort Sort) // // topological ordering re-life, such as task dependencies, the base layer is dependent should be completed before the task, such as several pieces of clothing to wear, must be first worn on the inside of the clothes after the outer coat wear public class TopologicalKahn { Digraph DG; List <Integer> order; // topological order of the vertices int [ ] indegree; public TopologicalKahn (Digraph DG) { the this .dg = DG; // Kahn algorithm, the topological sort // 1. statistics of all vertices into //2. the degree to 0 as a starting point, is added to the queue // 3. Remove from the apex of the queue until the queue is empty, the vertex of the vertex points -1 = 0 if the degree is queued , the third step loop // when present in the ring: there is less than the number of vertices of the final output end of the loop, there is also the number of vertices in the graph, or that there is not the degree of the vertex 0 of Order = new new the LinkedList <> () ; // 1. indegree = new new int [dg.v ()]; for ( int U = 0; U <dg.v (); U ++ ) { for ( int W: dg.adj (U)) { indegree [ W] ++ ; } } // 2. queue becomes 0 by sequential addition of the vertices of the queue <Integer> = queue new newThe LinkedList <> (); for ( int U = 0; U <dg.v (); U ++ ) IF (indegree [U] == 0 ) queue.add (U); // 3. the while (! Queue.isEmpty ()) { int U = queue.remove (); order.add (U); for ( int W: dg.adj (U)) { indegree [W] - ; IF (indegree [W] == 0) // If the degree is not 0, indicating that there are other points of the edge point queue.add (W); } } //4. If the level of the final output is less than the number of vertices that there is 0 to the number of vertices in the graph, indicating the presence ring IF (order.size () < dg.v ()) Order = null ; the this .dg = null ; } public Boolean isDAG () { // is a directed acyclic graph it? return null ! = Order; } public the Iterable <Integer> getOrder () { return Order; } public static void main (String [] args) { List <String> Books = new new the LinkedList <> (); books.add ( "AC" ); books.add ( "BC" ); books.add ( "CC" ); books.add ( "DC" ); SymblowDigraph SD = new new SymblowDigraph (Books); sd.addEdge ( " AC "," BC " ); sd.addEdge ( " BC "," CC " ); sd.addEdge ( " DC "," BC " ); // compiled file when a file is dependent b, b c document file is dependence, b d document file is dependent // so which files were first compiled? Is the most dependent of that file (a or d) should be first compiled. How to get the correct order of compilation? // AC -> bc -> c. sd.getGraph (); TopologicalKahn Top = new new TopologicalKahn (DG); IF (top.isDAG ()) { System.out.println ( . "Topology sequence file compilation priority order (high depth being dependent first be compiled) " ); for ( int I: top.getOrder ()) { System.out.println ( " "+ sd.getSymblow (I)); } } } }
Export
Topological sequence file compilation priority order (high depth is dependent first be compiled)
AC
DC
BC
CC
2. The depth-first post-order inverse +
// topological sorting // acyclic directed graph is a topological sort prerequisite // the topological sort, the vertex node depends precursor must have first appeared in front of him again (such a sequence is called topology sequence) // long as the above condition is satisfied sorting output sequence are topology (FIG therefore tend to have a plurality of topological order) (this process is called topological Sort Sort) // // topological ordering re-life, such as task dependencies, the base layer is dependent should be completed before the task, such as several pieces of clothing to wear, must be first worn on the inside of the clothes after the outer coat wear public class Topological { Digraph DG; DirectedCycle DC; DFOrder DFO; the Iterable <Integer> Order; // topology vertex order public topological (Digraph DG) { the this .dg = DG; DC = new new DirectedCycle (DG); IF(dc.hasCycle ()!) { // If the presence of a ring, not calculated topological sort DFO = new new DFOrder (DG); Order = dfo.reversePost (); // topology will use a depth-first ordering } the this .dg = null ; } public Boolean isDAG () { // is a directed acyclic graph it? return null ! = Order; } public the Iterable <Integer> getOrder () { return Order; } public static void main (String [] args) { List<String> Books = new new the LinkedList <> (); books.add ( "fish" ); books.add ( "mud" ); books.add ( "Zhao six" ); books.add ( "shrimp" ) ; books.add ( "fish" ); books.add ( "Shepherd" ); books.add ( "feed" ); books.add ( "cheap labor" ); SymblowDigraph SD = new new SymblowDigraph (Books); SD .addEdge ( "mud", "shrimp" ); sd.addEdge ( "shrimp", "fish" ); sd.addEdge ( "feed", "fish" ); sd.addEdge ( "small fish", "big fish" ); sd.addEdge ( "small fish", "cheap labor" ); sd.addEdge ( "small fish "," shepherd " ); sd.addEdge ( " big fish "," shepherd " ); sd.addEdge ( " cheap labor "," shepherd " ); sd.addEdge ( " big fish "," Zhao Exhibition of six " ); sd.addEdge ( " Shepherd "," Zhao six " ); sd.addEdge ( " cheap labor "," Zhao six " ); // mud was eating shrimp, shrimp are small fish to eat, feed is eating small fish, big fish eat the small fish, small fish eaten shepherd, small fish are eating cheap labor, big fish eat the shepherd, the big fish are Zhao six eat, eat cheap labor is Shepherd, Shepherd Zhao was eating six or cheap labor was eaten Zhao six // then the low end of the food chain (is dependent on) the top is the relationship? DG digraph = sd.getGraph (); Topological Top = new new Topological (DG); IF (top.isDAG ()) { System.out.println ( . "Topology-dependent sequence is close to the top row (in parallel are dependent on it, before and after the order is not important) " ); for ( int I: top.getOrder ()) { System.out.println ( " "+ sd.getSymblow (I)); } } } }
After generating inverse order
// based on a depth-first ordering vertices public class DFOrder { Digraph DG; Boolean [] Marked; Queue <Integer> pre; // preamble Queue <Integer> POST; // subsequent Stack <Integer> reversePost; // the inverse sequence public DFOrder (Digraph DG) { the this .dg = DG; Marked = new new Boolean [dg.v ()]; pre = new new ArrayDeque <> (); POST = new new ArrayDeque <> (); reversePost= new Stack<>(); for (int u = 0; u < dg.v(); u++) { if (!marked[u]) { dfs(u); } } this.dg = null; } private void dfs(int u) { pre.add(u); marked[u] = true; for (int v : dg.adj(u)) { if (!marked[v]) dfs(v); } post.add(u); reversePost.add(u); } public Iterable<Integer> pre() { return pre; } public Iterable<Integer> post() { return post; } public Iterable<Integer> reversePost() { List<Integer> rpList = new ArrayList<>(); while(reversePost.size() > 0){ rpList.add(reversePost.pop()); } return rpList; } public static void main(String[] args) { } }
Output:
Topological sequence near the top row is dependent (dependent on the parallel words, before and after the order is not important)
feed
mud
shrimp and
fish
fish
cheap labor
Shepherd
Zhao six