Suppose we have a set of tasks to complete and some tasks to start after other tasks are completed, so we have to be very careful about the order in which these tasks are executed.
If the order of these tasks is simple enough, we can use the list to store them, which is a good solution, so that we can know exactly the order of execution of the tasks. The problem is that sometimes the relationship between different tasks is very complex, and some tasks depend on two or more tasks, or in turn many tasks depend on themselves.
Therefore, we cannot model this problem through the data structure of a linked list or tree. The only logical data structure for this kind of problem is the graph. What kind of diagram do we need? Obviously, we need to have a map to describe the relationship, and it is not a circular graph, we call it a graph of the direction of the loop. To sort the graphs by topological sorting, the graphs must not be circular and forward. Why can't these graphs loop? The answer is clear, if the graph is circular, we cannot know which task is the priority and it is impossible to sort the tasks. Now all we have to do is sort each node in the diagram, form a strip of edges (u,v), and U execute before v. Then we can get the linear order of all the tasks and perform the task in this order and everything is OK.
For example, a topological sort of the following figure is "5 4 2 3 1 0". A diagram can have multiple topological sorts.
Another topology sort is "4 5 2 3 1 0". The first vertex of a topological sort is always in the degree of 0.
Method One
Now we can get the basic steps of this algorithm:
1. Construct the empty list L and s;2. Put all nodes that are not dependent on the node (0 in degrees) into l;3. When L has a node, perform the following steps: 3.1 L take out a node n (remove from L), and put S3.2 on each of the neighboring N nodes m, 3.2.1 Remove the Edge (n,m), (means to join the final result set s) 3.2.2 if M has no dependent node (in degrees 0), put M into L;
The core is: each time you select a node with a degree of 0, and then update its neighboring nodes of the degree.
This is a relatively intuitive algorithm, but also a common one. We use an array of degree[] to record the degrees of all vertices. The array is updated when the point is deleted.
Refer to the following code function: TopologicalSort1 ()
Method Two
Another way is to refer to DFS and make some changes to the depth-first traversal of the graph. We are sure that if there is an edge (u,v) in the graph, the vertex u will enter the list before the vertex v. Therefore, in the deep traversal, the stack is used to store the traversal order. Refer to the following code function: TopologicalSort2 ()
C + + implementation
Topology sorting algorithm implemented by C + + #include<iostream> #include <list> #include <stack>using namespace std;//Graph class graph{int V; Vertex number//adjacency table list<int> *adj; Topological sorting Method 2 auxiliary function void Topologicalsortrecall (int V, BOOL visited[], stack<int> &stack);p ublic:graph (int v) ; Add edge void Addedge (int v, int w); Topological ordering general method void TopologicalSort1 (); Topological sorting Method two void TopologicalSort2 ();}; graph::graph (int V) {this->v = V; Adj = new List<int>[v];} void Graph::addedge (int v, int w) {adj[v].push_back (w),//}//similar to depth-first traversal, and V adjacent vertices (and accessed) are placed in the stack void Graph:: Topologicalsortrecall (int V, BOOL visited[], stack<int> &stk) {//Mark V for visited visited[v] = true; Recursive invocation of List<int>::iterator I for each vertex; for (i = Adj[v].begin (); I! = Adj[v].end (); ++i) if (!visited[*i]) Topologicalsortrecall (*i, visited, St k); Save Vertex Stk.push (v);} Method Two, use recursive call to implement topological sort void graph::topologicalsort2 () {stack<int> stk; BOOL *visited = new BOOL[V]; for (int i = 0; i < V; i++) visited[i] = false; Each vertex is called once for (int i = 0; i < V; i++) if (visited[i] = = False) Topologicalsortrecall (I, visited, Stk); Print while (stk.empty () = = False) {cout << stk.top () << ""; Stk.pop (); }}//method one void Graph::topologicalsort1 () {list<int>::iterator j;int degree[v];//traverses all edges, calculates the in-degree for (int i=0; i<v; i+ +) {Degree[i] = 0;for (j = Adj[i].begin (); J! = Adj[i].end (); ++j) {degree[*j]++;}} List<int> zeronodes;//all points with a degree of 0 list<int> result;//all points in the 0 for (int i=0; i<v; i++) {if (degree[i] = = 0) { Zeronodes.push_back (i);}} while (Zeronodes.size () > 0) {int top = Zeronodes.back (), Zeronodes.pop_back (); Result.push_back (top); for (j = Adj[top] . Begin (); J! = Adj[top].end (); ++J) {degree[*j]--;//Delete and top adjacent edges, and update the other vertex's in degrees if (degree[*j] = 0) zeronodes.push_back (*j);}} Print the results for (j= Result.begin (); J! = Result.end (), j + +) cout << (*j) << "";} int main () { Create the graph graph G (6) in the text; G.addedge (5, 2); G.addedge (5, 0); G.addedge (4, 0); G.addedge (4, 1); G.addedge (2, 3); G.addedge (3, 1); cout << "Following is a topological Sort of the given graph using topologicalsort1\n"; G.topologicalsort1 (); cout << Endl; cout << "Following is a topological Sort of the given graph using topologicalsort2\n"; G.topologicalsort2 (); return 0;}
Reference: http://www.geeksforgeeks.org/topological-sorting/
Topological sequencing-graph theory