C/C + + code implementation of topological sorting of Graphs

AOV network:

A directed acyclic graph is called DAG graph for short.

The directed graph that uses vertex to represent activity and arc to represent the priority relationship between activities is called activity on vertex netwrk (AOV net for short)

Topology sorting:

The so-called topological ordering is to arrange all the vertices in the AOV network into a linear sequence.

Function: it can be used to judge whether there is a ring in a graph or network. The detection method is to sort the vertices of the directed graph. If all the vertices in the network are in its topological ordered sequence, there must be no rings in the AOV network, otherwise there are rings.
In addition to topological ordering, depth first traversal can also be used to determine whether a graph has rings or not.

Specific steps:

(1) Select a vertex without precursor in the directed graph and output it.
(2) Delete the vertex and all arcs with its tail from the graph (the code can be implemented by subtracting the degree of the vertex of the arc head by 1).
(3) Repeat (1) and (2) until there are no vertices without precursors.
(4) If the number of vertices output at this time is less than the number of vertices in the digraph, then there is a ring in the digraph, otherwise the output vertex sequence is a topological sequence.

Take the figure as an example:

The code is as follows:

#include<stdio.h>

#define MVNum 100
typedef char OtherInfo;
typedef char VerTexType;

//Adjacency table storage structure of Graphs
typedef struct ArcNode			//Edge node
{
	int adjvex;	//Adjacency region 
	struct ArcNode *nextarc;//Chain domain
	OtherInfo info;	//Data field 
}ArcNode;
typedef struct VNode			//Vertex information
{
	VerTexType data;//Data field 
	ArcNode *firstarc;//Chain domain
}VNode, AdjList[MVNum];
typedef struct                  //Adjacency table
{
	AdjList vertices;
	int vexnum, arcnum;
}ALGraph;

//Function declaration
int LocateVex(ALGraph G, char v);
void LinkAL(ALGraph &G, int i, int j);
void FindInDegree(ALGraph G, int indegree[]);
void printTopo(int topo[], int m);


//Adjacency table creating directed graph
void CreateUDG(ALGraph &G)
{
	G.vexnum = 6;						//Enter the total number of vertices and edges
	G.arcnum = 8;
	G.vertices[0].data = 'v1';			//Enter vertex information
	G.vertices[0].firstarc = NULL;
	G.vertices[1].data = 'v2';
	G.vertices[1].firstarc = NULL;
	G.vertices[2].data = 'v3';
	G.vertices[2].firstarc = NULL;
	G.vertices[3].data = 'v4';
	G.vertices[3].firstarc = NULL;
	G.vertices[4].data = 'v5';
	G.vertices[4].firstarc = NULL;
	G.vertices[5].data = 'v6';
	G.vertices[5].firstarc = NULL;

	int i, j;							//Input side information
	i = LocateVex(G, 'v1');
	j = LocateVex(G, 'v2');
	LinkAL(G, i, j);
	i = LocateVex(G, 'v1');
	j = LocateVex(G, 'v3');
	LinkAL(G, i, j);
	i = LocateVex(G, 'v1');
	j = LocateVex(G, 'v4');
	LinkAL(G, i, j);
	i = LocateVex(G, 'v3');
	j = LocateVex(G, 'v2');
	LinkAL(G, i, j);
	i = LocateVex(G, 'v3');
	j = LocateVex(G, 'v5');
	LinkAL(G, i, j);
	i = LocateVex(G, 'v4');
	j = LocateVex(G, 'v5');
	LinkAL(G, i, j);
	i = LocateVex(G, 'v6');
	j = LocateVex(G, 'v4');
	LinkAL(G, i, j);
	i = LocateVex(G, 'v6');
	j = LocateVex(G, 'v5');
	LinkAL(G, i, j);
}

//Build edge
void LinkAL(ALGraph &G, int i, int j)
{
	ArcNode *p1;
	p1 = new ArcNode;
	p1->adjvex = j;
	p1->nextarc = G.vertices[i].firstarc;						  //Head insertion
	G.vertices[i].firstarc = p1;
}

//Return vertex position subscript
int LocateVex(ALGraph G, char v)
{
	for (int i = 0; i < G.vexnum; i++)
	{
		if (G.vertices[i].data == v)
		{
			return i;
		}
	}
}

//Printout
void printGraph(ALGraph G)
{
	for (int i = 0; i < G.vexnum; i++)
	{
		printf("%d :", i);
		printf("v%d ->", i + 1);

		ArcNode *p;
		p = G.vertices[i].firstarc;
		while (p != NULL)
		{
			printf("%d->", p->adjvex);
			p = p->nextarc;
		}
		printf("\n");
	}
}

//Depth first traversal of adjacency table
bool visited[MVNum];
void DFS_AL(ALGraph G, int v)
{
	printf("v%c->", G.vertices[v].data);
	visited[v] = true;
	ArcNode *p;
	p = G.vertices[v].firstarc;
	while (p != NULL)
	{
		int w = p->adjvex;
		if (!visited[w])
		{
			DFS_AL(G, w);
		}
		p = p->nextarc;
	}
}



//Define stack
#define MAXSIZE 100
typedef struct
{
	int base[MAXSIZE];
	int *top;
	int stacksize;
}SqStack;
//initialization
int InitStack(SqStack &S)
{
	S.top = S.base;
	S.stacksize = MAXSIZE;
	return 1;
}
//Push 
int Push(SqStack &S, int e)
{
	if (S.top - S.base == S.stacksize) return 0;
	*S.top++ = e;
	return 1;
}
//Out of the stack
int Pop(SqStack &S, int &e)
{
	if (S.top == S.base) return 0;
	e = *--S.top;
	return 1;
}



//Topological sorting
int indegree[MVNum];		//Storage of vertex penetration
int topo[MVNum];			//Store the vertex number of topological sequence
SqStack S;					//Temporary access to 0 vertex
int TopologicalSort(ALGraph G, int topo[])
{
	ArcNode *p;
	int i, m = 0;				//m for counting
	FindInDegree(G, indegree);	//Calculate the entry degree of each vertex and store it in the index array
	InitStack(S);
	for (i = 0; i < G.vexnum; i++)
	{
		if (!indegree[i])
		{
			Push(S, i);			//Stack with 0
		}
	}

	while (S.base != S.top)
	{
		Pop(S, i);
		topo[m] = i;		//Stack in 0 and store in topo array
		m++;				//Count plus one
		p = G.vertices[i].firstarc;		//p points to the subsequent edge node
		while (p != NULL)
		{
			int k = p->adjvex;			//k is the vertex subscript value
			--indegree[k];				//Reduce the vertex's degree by 1 instead of deleting the edge
			if (indegree[k] == 0)		//If it is 0 after subtracting 1, it will be pushed
			{
				Push(S, k);
			}
			p = p->nextarc;				//Continue to the next subsequent edge node
		}
	}

	if (m < G.vexnum)  return 0;		//If the number of output vertices is less than the number of vertices in a thousand digraph, then there is a ring in the digraph
	else return m;						//Otherwise, the topological sorting is successful and there is no ring
}

//Find the degree of entry of each vertex
void FindInDegree(ALGraph G, int indegree[])
{
	//initialization
	for (int i = 0; i < G.vexnum; i++)
	{
		indegree[i] = 0;
	}

	ArcNode *p;
	//Traverse the entire adjacency table to find the access degree. The access degree of vertex is the total number of times in the adjacency table's edge nodes
	for (int j = 0; j < G.vexnum; j++)
	{
		p = G.vertices[j].firstarc;
		while (p != NULL)
		{
			indegree[p->adjvex]++;
			p = p->nextarc;
		}
	}
}

//Print topology sequence
void printTopo(int topo[], int m)
{
	printf("\n A topological sequence of the graph is:");
	for (int i = 0; i < m; i++)
	{
		printf("v%d->", topo[i]+1);
	}
}

int main()
{
	ALGraph G;
	CreateUDG(G);
	printGraph(G);

	int v = 0;
	printf("Depth first traversal:");
	DFS_AL(G, v);

	//Topological sorting
	printf("\n==========================\n");
	int loop = TopologicalSort(G, topo);
	if (loop == 0)
	{
		printf("\n Topology sorting failed, the graph has rings!\n");
	}
	else 
	{
		printf("\n Topology sorting succeeded,The picture is acyclic!");
		printTopo(topo, loop);		//Output topology sequence
	}
}

Operation result:

Tags: network less

Posted on Sun, 21 Jun 2020 05:45:12 -0400 by gumby51