1. Note: the idea in this code comes from s1mba. Worship the great God!

2. This code creates an adjacency table based on the adjacency matrix. The convenience of this is that in the adjacency matrix, we can intuitively show whether the two vertices are connected, and distinguish whether they are digraphs by whether they are symmetric matrices or not. This is very important when creating adjacent tables. Use if (g.arcs [i] [J] = = 1) to judge whether to create a new table node.

3. In addition, adding an entry field in to the vertex table of the adjacency table is also the finishing touch. This is to facilitate judging whether the node entry is 0, so as to decide whether to stack.

4. By the way, the stack container in STL library is used in this code, which is more convenient. Using array and subscript index to move around, the boundary conditions are very troublesome. Although arrays may be faster

5. We should think about the performance of topologicalsort in the adjacency table data structure. First traverse the adjacency list, put the content of nodes with a degree of 0 into the stack, and then select one by one from the stack. Use while (!ZeroDegreeNodeStack.empty()) as the loop condition, and start traversing from the linked list of nodes in the stack. The degree of each node in the subsequent linked list is --, and then judge whether it is 0. If it is 0, enter the stack.

6. During the above traversal, it should be noted that after the content of the node at the top of the stack is output, it is really necessary to output the stack, and then record the number of stack nodes cnt + +, but an auxiliary variable cur should be used to save the value of the element at the top of the stack for the initial conditions in the for loop.

7. Never put the stack.pop() operation behind the for loop, because this will cause the elements stacked in the for loop to be directly out of the stack and out of the stack before output, which is logically wrong!

## Upper Code:

#include <iostream> #include <stack> using namespace std; /** * 1.Using adjacency matrix to create graph, but it is more convenient to use adjacency table because of the need to delete vertices in topology sorting * Therefore, after we create the adjacency matrix of the graph, we use the adjacency matrix to create the adjacency table * 2.Because we often need to judge whether the penetration of a node is 0, we add a data field in to the vertex table of the adjacency table */ #define MaxVertexNum 100 #define Infinity 10000 //Adjacency matrix structure definition typedef struct { int vers[MaxVertexNum]; //vertex array int arcs[MaxVertexNum][MaxVertexNum]; //Edge array int vernum, arcnum; //Number of points and edges }AMGraph; //Table node structure definition of adjacency table typedef struct EdgeNode { int adjver; //Store the subscript of the adjacent node in the vertex table struct EdgeNode* next; //Pointer field to the next adjacent node }EdgeNode; //Definition of vertex table structure of adjacency table typedef struct { int in; //indegree int data; //The content of the storage node is the int value stored in the AOV network of this experiment EdgeNode* firstEdge; //Pointer field to the first adjacent node }VertexNode, AdjVerList[MaxVertexNum]; //Structure definition of adjacency table typedef struct { AdjVerList adjverList; int vernum, arcnum; //Number of vertices and edges }adjlist, *AdjList; //The first one without a pointer is to allocate space void CreatAM(AMGraph &G) { //Initialize adjacency matrix cout << "Please enter the number of vertices and edges of the graph:" << endl; cin >> G.vernum >> G.arcnum; for (int i = 1; i <= G.vernum; i++) { G.vers[i] = i; } for (int i = 1; i <= G.vernum; i++) { for (int j = 1; j <= G.vernum; j++) { G.arcs[i][j] = 0; } } G.arcs[1][2] = 1; G.arcs[1][3] = 1; G.arcs[2][4] = 1; G.arcs[3][4] = 1; G.arcs[4][5] = 1; } void CreatAdjList(AMGraph G, AdjList &AL) { //Create adjacency table EdgeNode* p; AL = new adjlist; AL->vernum = G.vernum; AL->arcnum = G.arcnum; for (int i = 1; i <= G.vernum; i++) { //initialization AL->adjverList[i].data = G.vers[i]; //Node information replication AL->adjverList[i].in = 0; AL->adjverList[i].firstEdge = NULL; } for (int i = 1; i <= G.vernum; i++) { for (int j = 1; j <= G.vernum; j++) { if (G.arcs[i][j] == 1){ //If there are edges p = new EdgeNode; p->adjver = j; //The subscript of the adjacent node in the vertex table p->next = AL->adjverList[i].firstEdge; //Head insertion AL->adjverList[i].firstEdge = p; AL->adjverList[j].in++; //Note that this is j! } } } } void TopologicalSort(AdjList AL) { EdgeNode* p; int cnt = 0; //Count the number of deleted nodes to judge whether it is a directed acyclic graph stack<int> ZeroDegreeNodeStack; //Stack with storage degree of 0 for (int i = 1; i <= AL->vernum; i++) { if (AL->adjverList[i].in == 0) { ZeroDegreeNodeStack.push(i); //Put the content of the node on the stack } } while (!ZeroDegreeNodeStack.empty()) { cout << ZeroDegreeNodeStack.top() << "->"; //Output node content int cur = ZeroDegreeNodeStack.top(); //Auxiliary variable ZeroDegreeNodeStack.pop(); cnt++; for (p = AL->adjverList[cur].firstEdge; p != NULL; p = p->next) { AL->adjverList[p->adjver].in--; if (AL->adjverList[p->adjver].in == 0) { //If you delete this node and the degree decreases by 1 and becomes 0, it will be put into the stack ZeroDegreeNodeStack.push(p->adjver); } }//for }//while cout << endl; if (cnt == AL->vernum) cout << "Should AOV Net is a directed acyclic graph!" << endl; else cout << "Should AOV A net is not a directed acyclic graph" << endl; } int main() { AMGraph G; //adjacency matrix AdjList AL; //Adjacency table CreatAM(G); //Create adjacency matrix CreatAdjList(G, AL); //Create adjacency table based on adjacency matrix cout << "The result of topology sorting is:" << endl; TopologicalSort(AL); }