12.4拓扑序列

拓扑序列

拓扑排序(Topological Sorting)是处理有向无环图(DAG)的关键算法,用于确定顶点的线性顺序,使得所有有向边均从排在前面的元素指向后面的元素。以下是C++实现拓扑排序的两种经典方法及其详细解析:

一、算法原理

1. Kahn算法(基于入度的贪心算法)
  • 核心思想:不断删除入度为0的顶点,直到图为空或存在环。
  • 步骤
    1. 统计每个顶点的入度。
    2. 将入度为0的顶点加入队列。
    3. 依次取出队列中的顶点,将其邻接顶点入度减1,若减至0则入队。
    4. 若结果顶点数 ≠ 总顶点数,说明存在环。
2. 基于DFS的后序遍历法
  • 核心思想:通过深度优先搜索遍历图,按完成时间的逆序输出顶点。
  • 步骤
    1. 对未访问顶点进行DFS。
    2. 递归访问邻接顶点,完成后将当前顶点压入栈。
    3. 最终栈中元素即为拓扑序列。
    4. 若DFS中发现已访问但未完成的顶点,说明存在环。

二、C++代码实现

方法1:Kahn算法
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> topologicalSortKahn(int n, vector<vector<int>>& edges) {
   
    vector<vector<int>> adj(n);
    vector<int> inDegree(n, 0);
    // 构建邻接表并统计入度
    for (auto& e : edges) {
   
        adj[e[0]].push_back(e[1]);
        inDegree[e[1]]++;
    }

    queue<int> q;
    for (int i = 0; i < n; ++i) {
   
        if (inDegree[i] == 0) q.push(i);
    }

    vector<int> res;
    while (!q.empty()) {
   
        int u = q.front();
        q.pop();
        res.push_back(u);
        for (int v : adj[u]) {
   
            if (--inDegree[v] == 0) {
   
                q.push(v);
            }
        }
    }

    if (res.size() != n) {
   
        cout << "图中有环!" << endl;
        return {
   };
    }
    return res;
}
方法2:基于DFS的算法
#include <stack>
#include <vector>
#include <iostream>
using namespace std;

bool dfs(int u, vector<int>& visited, vector<vector<int>>& adj, stack<int>& stk) {
   
    if (visited[u] == 1) return false; // 发现环
    if (visited[u] == 2) return true;  // 已处理完毕
  
    visited[u] = 1; // 标记为正在访问
    for (int v : adj[u]) {
   
        if (!dfs(v, visited, adj, stk)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵鑫亿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值