C++ outputs a topological sequence of directed acyclic graph


1. Topological sequence

The concept of topological sequence

In a directed acyclic graph, if there is an arc <i, j >, then in the topological sequence, i must be in front of j. A linear sequence with this property is called a topologically ordered sequence.

Application of topological sequence

(1) The execution sequence of several related events can be obtained;
(2) It can be judged whether there is a loop (loop) in a directed graph.


2. Topological sorting steps

(1) Select a vertex with an in-degree of 0 (that is, no predecessor vertex) in the directed graph.

(2) Save the vertex to the output result, delete the vertex and the arc connected to the vertex from the graph.

(3) Repeat steps (1) and (2) until all vertices have been output or there is no vertex whose predecessor is 0 in the graph.


3. Example

Insert picture description here
As shown in the figure,
(1) Select the vertex v0 whose in-degree is 0, save it in the array result, and delete v0 and the arc connected to it.

Insert picture description here
(2) Continue to select the vertices with in-degree 0. You can select v3 or v1. Here, select v1, save it to the array result, and delete v1 and the arcs connected to it.

Insert picture description here
(3) Continue to select the vertex with in-degree 0. You can select v3 or v2, here select v2, save it to the array result, delete v2 and the arc connected to it.

Insert picture description here
(4) Continue to select the vertex whose in-degree is 0, which is v3, save it to the array result, delete v3 and the arc connected to it. At this time, only v4 is left, and its in-degree is 0, continue to select once and save it to the array result, and the sorting ends.

The data of the result array: 0, 1, 2, 3, 4 is a topological sequence.


4. Code implementation

#include<iostream>
#include<queue>
#include<vector>
using namespace std;

#define Max 9999
int n, m; // n为顶点数,m为边数
int G[Max][Max];
int inDegree[Max];
vector<int> result;//记录结果

void topsort()
{
    
    
	queue<int> node; // 用来保存入度为 0 的顶点
	for (int i = 0; i < n; ++i)
	{
    
    
		if (inDegree[i] == 0)
		{
    
    
			node.push(i);
			inDegree[i] = -1;
		}
	}
	if (node.empty())
	{
    
    
		cout << "该图无拓扑排序" << endl;
		return;
	}
	while (!node.empty())
	{
    
     
		int temp = node.front();
		node.pop();
		for (int i = 0; i < n; ++i)
		{
    
    
			if (G[temp][i] != 0)  //删除与所选顶点相连的弧并让弧的另一个顶点入度减一
			{
    
    
				inDegree[i]--;
				G[temp][i] = 0;
			}
			if (inDegree[i] == 0)  //若顶点的入度为 0 ,则将其加入队列
			{
    
    
				node.push(i);
				inDegree[i] = -1;
			}
		}
		result.push_back(temp);
	}
	if (result.size() < n) // 判断图中的顶点是否全部加入
	{
    
    
		cout << "该图无拓扑排序" << endl;
	}
	else
	{
    
    
		cout << "该图的一个拓扑排序为:" << endl;
		for (int i = 0; i < result.size(); ++i)
		{
    
    
			cout << result[i] << " ";
		}
	}
}
int main()
{
    
    
	cout << "输入顶点数:";
	cin >> n;
	cout << "输入边数:";
	cin >> m;
	cout << "输入各边的信息:";
	fill(G[0], G[0] + Max * Max, 0);
	fill(inDegree, inDegree + Max, 0);
	int u, v; //u为前驱节点,v为后继节点
	for (int i = 0; i < m; ++i)
	{
    
    
		cin >> u >> v;
		G[u][v]++;
		inDegree[v]++;  //入度加一
	}
	topsort();

	return 0;
}

Input and output information:Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_46027243/article/details/108916705