拓扑排序的核心算法:BFS应用与实践

news/2025/2/25 13:36:49

目录

一、拓扑排序简介

二、BFS解决拓扑排序的步骤

三、C++实现

四、代码解释

五、总结


一、拓扑排序简介

        拓扑排序是对有向无环图(DAG)进行排序的一种方法,使得对于图中的每一条有向边 (u, v),u 在排序中总是位于 v 的前面。拓扑排序的结果可能不唯一。

二、BFS解决拓扑排序的步骤

  1. 初始化:计算每个顶点的入度(即指向该顶点的边的数量),并将所有入度为0的顶点加入队列。

  2. BFS遍历

    • 从队列中取出一个顶点,将其添加到拓扑排序的结果中。

    • 移除该顶点的所有出边,即将其邻接顶点的入度减1。

    • 如果某个邻接顶点的入度变为0,则将其加入队列。

  3. 结束条件:当队列为空时,如果拓扑排序结果中的顶点数量与图中的顶点数量相同,则排序成功;否则,图中存在环,无法进行拓扑排序。

三、C++实现

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

vector<int> topologicalSort(int V, vector<vector<int>>& adj) {
    vector<int> inDegree(V, 0);
    for (int u = 0; u < V; ++u) {
        for (int v : adj[u]) {
            inDegree[v]++;
        }
    }

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

    vector<int> result;
    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) {
        cout << "图中存在环,无法进行拓扑排序" << endl;
        return {};
    }

    return result;
}

int main() {
    int V = 6;
    vector<vector<int>> adj = {
        {2, 3},
        {3, 4},
        {5},
        {5},
        {5},
        {}
    };

    vector<int> sortedOrder = topologicalSort(V, adj);
    for (int u : sortedOrder) {
        cout << u << " ";
    }
    cout << endl;

    return 0;
}

四、代码解释

  • inDegree 数组用于存储每个顶点的入度。

  • adj 是图的邻接表表示。

  • topologicalSort 函数实现了拓扑排序的逻辑。

  • 如果排序结果中的顶点数量与图中的顶点数量不一致,说明图中存在环。

五、总结

        使用BFS进行拓扑排序是一种高效的方法,时间复杂度为O(V + E),其中V是顶点数量,E是边数量。这种方法不仅适用于拓扑排序,还可以用于检测图中是否存在环。


http://www.niftyadmin.cn/n/5865556.html

相关文章

AIGC-LLAMA模型介绍

LLAMA模型介绍 LLAMA模型介绍LLAMA模型架构模型特点 训练数据代码示例 LLAMA模型介绍 LLAMA&#xff08;LLaMA, Large Language Model Meta AI&#xff09;是Meta&#xff08;前Facebook&#xff09;开发的一系列大型语言模型。LLAMA模型家族旨在提供高效、灵活的语言处理能力…

Java Web框架篇之Spring

Java Web系列文章汇总贴: Java Web知识总结汇总 为什么要有Spring(IoC) Web发展的几个阶段 &#xff08;1&#xff09;初级阶段&#xff1a;使用Model1(JSPJavaBean)/Model2(JspServletJavaBean)/三层模型(表示层(JSP/Servlet)业务逻辑层持久化层)进行开发&#xff1b;&#…

服务器租用的价格受哪些因素影响?

1、 服务器配置 租用服务器配置的成本占租用服务器成本的关键部分。如果服务器配置完善、功能完善、臭名昭著&#xff0c;那么租赁价格肯定会高于所有其他级别的普通服务器。 2、 服务器防御 租用服务器的成本与其安全保护能力成正比。例如&#xff0c;移动游戏和金融易受DDoS和…

归并排序 Listnode* vector<int> vector<ListNode*>

加粗样式 ListNode* merge(ListNode* l1,ListNode* l2){ListNode* dummyheadnew ListNode(0);ListNode* curdummyhead;while(l1&&l2){if(l1->val>l2->val){cur->nextl2;l2l2->next;curcur->next;}else if(l1->val<l2->val){cur->nextl1…

Megatron-LM:使用模型并行训练数十亿参数的语言模型

摘要 最近在语言建模方面的工作表明&#xff0c;训练大型Transformer模型能够推动自然语言处理应用的技术前沿。然而&#xff0c;由于内存限制&#xff0c;训练非常大的模型可能相当困难。在这项工作中&#xff0c;我们展示了训练极大Transformer模型的技术&#xff0c;并实现…

GoFly框架中集成Bolt 和badfer两个Go语言嵌入式键值数据库

本插件集成了Bolt 和badfer两个纯Go实现的快速的嵌入式K/V数据库&#xff0c;方便开发时本地存储使用。插件集成Bolt 和badfer两个&#xff0c;如果确定使用其中一个&#xff0c;也可以把其中不用的一个删除&#xff0c;不删除也不会有任何影响。 插件使用说明 1.安装插件 到…

GitHub免密操作与跨服务器通行:SSH密钥一站式配置指南

作为开发者,与GitHub的安全交互和远程服务器的高效管理是日常工作的核心技能。本文将从零开始,教你如何配置GitHub的SSH密钥认证,并实现免密码远程登录Linux服务器。 一、为什么需要SSH密钥? 更安全的认证方式:相比传统密码,密钥认证几乎无法被暴力破解操作便捷性:免去每…

设计模式教程:策略模式(Strategy Pattern)

一、概述 策略模式&#xff08;Strategy Pattern&#xff09; 是一种行为型设计模式&#xff0c;旨在定义一系列算法&#xff08;或行为&#xff09;&#xff0c;并将它们封装到独立的类中&#xff0c;使得它们可以互相替换。策略模式让算法的变化独立于使用算法的客户端&…