当前位置: 首页 > news >正文

C++ 基于广度优先搜索(BFS)的拓扑排序算法

一:概述

        Kahn 拓扑排序算法是一种基于入度的广度优先搜索方法。它通过反复选择入度为 0 的节点加入结果序列,并移除相关边、更新入度,直到所有节点处理完毕。若最后结果中节点数小于图中节点总数,则说明图中存在环,拓扑排序失败。该算法时间复杂度为 O(V+E),既高效又能检测环,是处理任务依赖等问题的常用方法。

二:实现

#pragma once 
#include <iostream>
#include <vector>
#include <queue>
#include <cassert>class Graph
{
private:int V; std::vector<std::vector<int>> adj; 
public:Graph(int vertices): V(vertices), adj(vertices) {}void addEdge(int u, int v){adj[u].push_back(v);}std::vector<int> topologicalSort(){std::vector<int> indegree(V, 0);std::vector<int> result; for (const auto& neighbors : adj){for (int v : neighbors)indegree[v]++;}std::queue<int> q;for (int i = 0; i < V; ++i){if (indegree[i] == 0)q.push(i);}while (!q.empty()){int u = q.front();q.pop(); result.push_back(u);for (int v : adj[u]){if (--indegree[v] == 0)q.push(v);}}if (result.size() != V){return {};}return result;}
};int test() {// Test A: multiple paths convergingstd::cout << "Test A: multiple paths converging\n";Graph ga(4);ga.addEdge(0, 1);ga.addEdge(0, 2);ga.addEdge(1, 3);ga.addEdge(2, 3);auto ans_a = ga.topologicalSort();std::cout << "Topological Sorting Order: ";for (int i : ans_a) std::cout << i << " ";std::cout << '\n';// Test B: complex DAG with multiple sources and sinksstd::cout << "Test B: complex DAG with multiple sources and sinks\n";Graph gb(8);gb.addEdge(0, 1);gb.addEdge(0, 3);gb.addEdge(1, 4);gb.addEdge(3, 4);gb.addEdge(4, 6);gb.addEdge(4, 7);gb.addEdge(5, 6);auto ans_b = gb.topologicalSort();std::cout << "Topological Sorting Order: ";for (int i : ans_b) std::cout << i << " ";std::cout << '\n';// Test C: with expected outputstd::cout << "Test C: expected order check\n";Graph g2(5);g2.addEdge(0, 1);g2.addEdge(0, 2);g2.addEdge(1, 2);g2.addEdge(2, 3);g2.addEdge(1, 3);g2.addEdge(2, 4);auto ans_c = g2.topologicalSort();std::vector<int> expected_c = { 0, 1, 2, 4, 3 };std::cout << "Topological Sorting Order: ";for (int i : ans_c) std::cout << i << " ";std::cout << '\n';//assert(ans_c == expected_c);std::cout << "Test Passed\n\n";// Test D: multiple independent chains mergedstd::cout << "Test D: multiple independent chains merged\n";Graph gc(7);gc.addEdge(0, 1);gc.addEdge(1, 2);gc.addEdge(2, 3);gc.addEdge(3, 4);gc.addEdge(6, 4);gc.addEdge(5, 4);auto ans_d = gc.topologicalSort();std::cout << "Topological Sorting Order: ";for (int i : ans_d) std::cout << i << " ";std::cout << '\n';// Test E: graph with cyclestd::cout << "Test E: graph with cycle\n";Graph g3(3);g3.addEdge(0, 1);g3.addEdge(1, 2);g3.addEdge(2, 0);try {g3.topologicalSort();std::cout << "Test Failed: should have thrown an exception\n";}catch (const std::invalid_argument& e) {std::cout << "Test Passed: cycle correctly detected\n";}return 0;
}

http://www.dtcms.com/a/268299.html

相关文章:

  • 20250706-9-Docker快速入门(下)-Docker在线答疑_笔记
  • Linux 内存分配理论与水位机制全解
  • Mybatis--动态SQL
  • 前端防抖Debounce如何实现
  • Kafka “假死“现象深度解析与解决方案
  • JavaScript 中导入模块时,确实不需要显式地写 node_modules 路径。
  • week2
  • 基于 Rust 的前端工具基本实现
  • 【它加上100是一个完全平方数,再加上168又是一个完全平方数】2022-7-17
  • 第十六节:第三部分:多线程:线程安全问题、取钱问题的模拟
  • 浅谈漏洞扫描与工具
  • 计算机网络实验——互联网安全实验
  • 10046 解决 Oracle error
  • NLP文本预处理
  • Chunking-free RAG
  • 拼好题(各个平台的零散题目)
  • vue什么时候可以用index作为:key的索引
  • Vue计算属性(computed)全面解析:原理、用法与最佳实践
  • Python库 python-pyper 的详细使用(优秀的并发数据处理框架)
  • 第一次ctf比赛的赛后复现记录
  • ​保持矩阵秩不变的乘法
  • SoloSpeech:从混合音频中提取目标语音
  • 下载安装 com0com
  • Android16之解决报错:ckati: no such file or directory(二百四十九)
  • ros-noetic搭建turtlebot3测试
  • 数据运营策略 —— B-O价值模型
  • 【机器学习笔记Ⅰ】12 逻辑回归
  • 《Redis》缓存与分布式锁
  • usrp b210 亚克力外壳
  • 【机器学习笔记Ⅰ】11 多项式回归