拓扑排序C++实现
定义
在图论中,由一个有向无环图DAG的顶点组成的序列,当且且仅当满足每个顶点出现且仅出现一次以一个顶点在序列中的另一个顶点不存在后者到前者的路径这两个条件时,称该序列为该图的一个拓扑排序,每个有向无环图都有一个或多个拓扑排序
算法思路
找到图中一个没有前驱的顶点存入,从图中删除该顶点和及所有以其为起点的所有边,直到删除所有的顶点,或者当前图中不存在无前驱的结点,即存在环。
拓扑排序
bool AdjacentMatrix::topologicalSort() {
stack<int> s;
for (int i = 0; i < vextexNumber; i++) {
if (inDegree[i] == 0) {
s.push(i);//将结点入度为0的顶点的入栈
}
}
int cnt = 0;// 存在环
while (!s.empty()) {
int current = s.top();
topologicalSequence.push_back(current);
s.pop();//取出度为0顶点
cnt++;
for (int i = 0; i < vextexNumber; i++) {
if (matrix[current][i]) {
// 删除所有以其为起点的所有的边
if (!(--inDegree[i])) {
s.push(i);
}
}
}
}
return cnt >= vextexNumber;//若计数比顶点数小,则存在环
}
实现代码
/*
author : eclipse
email : eclipsecs@qq.com
time : Mon Jun 08 12:09:26 2020
*/
#include <bits/stdc++.h>
using namespace std;
class AdjacentMatrix {
private:
vector< vector<int> > matrix;
vector<int> inDegree;
vector<int> topologicalSequence;
int vextexNumber;
bool topologicalSort();
public:
AdjacentMatrix(int vextexNumber, vector<pair<int, int> > graph);
void topological();
};
AdjacentMatrix::AdjacentMatrix(int vextexNubmer, vector<pair<int, int> > graph) {
this->vextexNumber = vextexNubmer;
matrix.resize(vextexNubmer);
inDegree.resize(vextexNubmer);
for (int i = 0; i < vextexNubmer; i++) {
matrix[i].resize(vextexNubmer);
for (int j = 0; j < vextexNubmer; j++) {
matrix[i][j] = 0;
}
inDegree[i] = 0;
}
for (int i = 0; i < graph.size(); i++) {
matrix[graph[i].first][graph[i].second] = 1;
inDegree[graph[i].second]++;
}
}
bool AdjacentMatrix::topologicalSort() {
stack<int> s;
for (int i = 0; i < vextexNumber; i++) {
if (inDegree[i] == 0) {
s.push(i);
}
}
int cnt = 0;
while (!s.empty()) {
int current = s.top();
topologicalSequence.push_back(current);
s.pop();
cnt++;
for (int i = 0; i < vextexNumber; i++) {
if (matrix[current][i]) {
if (!(--inDegree[i])) {
s.push(i);
}
}
}
}
return cnt >= vextexNumber;
}
void AdjacentMatrix::topological() {
if (topologicalSort()) {
for (int i = 0; i < topologicalSequence.size(); i++) {
printf("%d ", topologicalSequence[i] + 1);
}
} else {
printf("Exist circle!\n");
}
}
int main(int argc, char const *argv[]) {
int N;
int vextexNumber;
scanf("%d%d", &vextexNumber, &N);
vector<pair<int, int> > graph;
for (int i = 0 ; i < N; i++) {
int from, to;
scanf("%d%d", &from, &to);
graph.push_back(make_pair(from, to));
}
AdjacentMatrix *adjacentMatrix = new AdjacentMatrix(vextexNumber, graph);
adjacentMatrix->topological();
return 0;
}
测试数据
5 7
0 1
0 3
1 2
1 3
2 4
3 2
3 4
输出数据
1 2 4 3 5
鸣谢
最后
- 由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解!