本关任务:实现 graph.cpp 里的函数void TopSort(ALGraph *G),求除拓扑排序的一个序列。
时间: 2025-01-05 13:43:57 浏览: 3
拓扑排序(Topological Sort)是一种对有向无环图(DAG, Directed Acyclic Graph)进行线性排序的方法,使得对于每一条有向边 uv,从顶点 u 到顶点 v,u 在拓扑排序中出现在 v 之前。拓扑排序常用于任务调度、编译顺序等场景。
在实现拓扑排序时,常用的算法是 Kahn 算法和深度优先搜索(DFS)算法。下面我将介绍 Kahn 算法的实现步骤:
1. 统计每个顶点的入度(即指向该顶点的边数)。
2. 将所有入度为 0 的顶点加入队列。
3. 重复以下步骤,直到队列为空:
- 从队列中取出一个顶点,加入拓扑排序序列。
- 遍历该顶点的所有邻接顶点,将它们的入度减 1。
- 如果某个邻接顶点的入度变为 0,将其加入队列。
4. 检查拓扑排序序列中的顶点数量是否等于图中的顶点数量。如果相等,说明拓扑排序成功;否则,图中有环,无法进行拓扑排序。
下面是一个示例代码,展示如何在 `graph.cpp` 中实现 `TopSort` 函数:
```cpp
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct Edge {
int to;
};
struct ALGraph {
int numVertices;
vector<vector<Edge>> adjList;
};
void TopSort(ALGraph *G) {
vector<int> inDegree(G->numVertices, 0);
queue<int> q;
vector<int> result;
// 计算每个顶点的入度
for (int i = 0; i < G->numVertices; ++i) {
for (const auto &edge : G->adjList[i]) {
inDegree[edge.to]++;
}
}
// 将所有入度为 0 的顶点加入队列
for (int i = 0; i < G->numVertices; ++i) {
if (inDegree[i] == 0) {
q.push(i);
}
}
// 进行拓扑排序
while (!q.empty()) {
int u = q.front();
q.pop();
result.push_back(u);
for (const auto &edge : G->adjList[u]) {
inDegree[edge.to]--;
if (inDegree[edge.to] == 0) {
q.push(edge.to);
}
}
}
// 检查拓扑排序是否成功
if (result.size() == G->numVertices) {
cout << "Topological Sort: ";
for (const auto &vertex : result) {
cout << vertex << " ";
}
cout << endl;
} else {
cout << "Graph has a cycle, topological sort is not possible." << endl;
}
}
int main() {
// 示例图
ALGraph G;
G.numVertices = 4;
G.adjList.resize(4);
// 添加边
G.adjList[0].push_back({1});
G.adjList[0].push_back({2});
G.adjList[1].push_back({3});
G.adjList[2].push_back({3});
// 进行拓扑排序
TopSort(&G);
return 0;
}
```
在这个示例中,我们首先计算每个顶点的入度,然后将所有入度为 0 的顶点加入队列。接下来,我们从队列中取出一个顶点,加入拓扑排序序列,并将其所有邻接顶点的入度减 1。如果某个邻接顶点的入度变为 0,将其加入队列。重复这个过程,直到队列为空。最后,我们检查拓扑排序序列中的顶点数量是否等于图中的顶点数量,以确定拓扑排序是否成功。
阅读全文