The adjacency table is used to represent AOV network and judge whether it is a directed acyclic graph

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

//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

//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 << << "->"; //Output node content
		int cur =; //Auxiliary variable
		for (p = AL->adjverList[cur].firstEdge; p != NULL; p = p->next) {
			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
	cout << endl;
	if (cnt == AL->vernum)
		cout << "Should AOV Net is a directed acyclic graph!" << endl;
		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;

Tags: Algorithm data structure linked list

Posted on Fri, 26 Nov 2021 22:09:05 -0500 by fekaduw