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

【JavaScript 算法】拓扑排序:有向无环图的应用

在这里插入图片描述

🔥 个人主页:空白诗

在这里插入图片描述

文章目录

    • 一、算法原理
    • 二、算法实现
      • 方法一:Kahn算法
      • 方法二:深度优先搜索(DFS)
      • 注释说明:
    • 三、应用场景
    • 四、总结

在这里插入图片描述

拓扑排序(Topological Sorting)是一种线性排序方法,适用于有向无环图(DAG, Directed Acyclic Graph),它能够为图中的节点安排一个线性序列,使得对于图中的每一条有向边(u, v),顶点u在序列中出现在顶点v之前。拓扑排序在许多实际应用中都有重要作用,如任务调度、课程安排、编译依赖等。本文将详细介绍拓扑排序的原理、实现及其应用。


一、算法原理

拓扑排序的基本思想是:

  1. 选择一个入度为0的节点,将其输出到排序结果,并从图中删除该节点及其关联的所有边。
  2. 重复步骤1,直到所有节点都被输出,或者图中仍存在入度不为0的节点(此时图中存在环,无法进行拓扑排序)。

常用的两种实现拓扑排序的方法是Kahn算法和深度优先搜索(DFS)。


二、算法实现

方法一:Kahn算法

DFS

Kahn算法利用队列实现拓扑排序,通过不断删除入度为0的节点来构建拓扑序列。

/*** Kahn算法实现拓扑排序* @param {Object} graph - 图的邻接表表示* @return {string[]} - 拓扑排序结果*/
function kahnTopologicalSort(graph) {const inDegree = {}; // 记录每个节点的入度const queue = []; // 存储入度为0的节点const result = []; // 存储拓扑排序结果// 初始化入度表for (const node in graph) {inDegree[node] = 0;}// 计算每个节点的入度for (const node in graph) {for (const neighbor of graph[node]) {inDegree[neighbor]++;}}// 将入度为0的节点加入队列for (const node in inDegree) {if (inDegree[node] === 0) {queue.push(node);}}// 处理队列中的节点while (queue.length > 0) {const node = queue.shift(); // 取出队首节点result.push(node); // 将节点加入拓扑排序结果// 减少相邻节点的入度for (const neighbor of graph[node]) {inDegree[neighbor]--;// 如果相邻节点的入度为0,加入队列if (inDegree[neighbor] === 0) {queue.push(neighbor);}}}// 检查是否存在环if (result.length !== Object.keys(graph).length) {throw new Error("图中存在环,无法进行拓扑排序");}return result;
}// 示例
const graph = {A: ['C'],B: ['C', 'D'],C: ['E'],D: ['F'],E: ['H', 'F'],F: ['G'],G: [],H: []
};console.log(kahnTopologicalSort(graph)); // 输出: [ 'A', 'B', 'D', 'C', 'E', 'F', 'H', 'G' ]

方法二:深度优先搜索(DFS)

DFS

DFS方法通过递归遍历图,将访问过的节点存入栈中,最终从栈顶依次取出节点构建拓扑序列。

/*** 深度优先搜索实现拓扑排序* @param {Object} graph - 图的邻接表表示* @return {string[]} - 拓扑排序结果*/
function dfsTopologicalSort(graph) {const visited = new Set(); // 记录已访问的节点const stack = []; // 存储拓扑排序结果/*** 递归函数:DFS遍历节点* @param {string} node - 当前节点*/function dfs(node) {if (visited.has(node)) return;visited.add(node); // 标记节点为已访问for (const neighbor of graph[node]) {dfs(neighbor); // 递归访问相邻节点}stack.push(node); // 当前节点处理完毕,加入栈中}// 遍历所有节点,进行DFSfor (const node in graph) {dfs(node);}return stack.reverse(); // 返回栈的逆序,即拓扑排序结果
}// 示例
console.log(dfsTopologicalSort(graph)); // 输出: [ 'B', 'D', 'A', 'C', 'E', 'H', 'F', 'G' ]

注释说明:

  1. Kahn算法

    • inDegree:记录每个节点的入度。
    • queue:存储入度为0的节点。
    • result:存储拓扑排序结果。
    • 初始化入度表,并计算每个节点的入度。
    • 将入度为0的节点加入队列,处理队列中的节点,更新相邻节点的入度。
    • 最终检查是否存在环,返回拓扑排序结果。
  2. DFS方法

    • visited:记录已访问的节点。
    • stack:存储拓扑排序结果。
    • 递归遍历节点,将访问过的节点存入栈中,最终返回栈的逆序。

三、应用场景

  1. 任务调度:根据任务之间的依赖关系,确定任务的执行顺序。
  2. 课程安排:根据课程的先修关系,确定课程的学习顺序。
  3. 编译依赖:根据文件的依赖关系,确定编译的顺序。
  4. 数据处理:根据数据的依赖关系,确定处理的顺序。

四、总结

拓扑排序是一种用于有向无环图(DAG)的线性排序方法,通过Kahn算法和DFS方法可以实现拓扑排序,广泛应用于任务调度、课程安排、编译依赖和数据处理等场景。理解和掌握拓扑排序算法,对于解决实际问题具有重要意义。


相关文章:

【JavaScript 算法】拓扑排序:有向无环图的应用

🔥 个人主页:空白诗 文章目录 一、算法原理二、算法实现方法一:Kahn算法方法二:深度优先搜索(DFS)注释说明: 三、应用场景四、总结 拓扑排序(Topological Sorting)是一种…...

Fastgpt本地或服务器私有化部署常见问题

一、错误排查方式 遇到问题先按下面方式排查。 docker ps -a 查看所有容器运行状态,检查是否全部 running,如有异常,尝试docker logs 容器名查看对应日志。容器都运行正常的,docker logs 容器名 查看报错日志带有requestId的,都是 OneAPI 提示错误,大部分都是因为模型接…...

基于深度学习的股票预测

基于深度学习的股票预测是一项复杂且具有挑战性的任务,涉及金融数据的分析和预测。其目的是利用深度学习模型来预测股票价格的走势,从而帮助投资者做出更为准确的投资决策。以下是对这一领域的系统介绍: 1. 任务和目标 股票预测的主要任务和…...

UNiapp 微信小程序渐变不生效

开始用的一直是这个,调试一直没问题,但是重新启动就没生效,经查询这个不适合小程序使用:不适合没生效 background-image:linear-gradient(to right, #33f38d8a,#6dd5ed00); 正确使用下面这个: 生效,适合…...

FinClip 率先入驻 AWS Marketplace,加速全球市场布局

近日,凡泰极客旗下的小程序数字管理平台 FinClip 已成功上线亚马逊云科技(AWS)Marketplace。未来,FinClip 将主要服务于海外市场的开放银行、超级钱包、财富管理、社交电商、智慧城市解决方案等领域。 在全球市场的多样性需求推动…...

ChatGPT对话:Windows如何将Python训练模型转换为TensorFlow.js格式

【编者按】编者目前正在做手机上的人工智能软件,第一次做这种工作,从一些基本工作开始与ChatGPT交流。对初学者应该有帮助。 一天后修改文章补充内容: 解决TensorFlow 2.X与TensorFlow Decision Forests版本冲突问题: 在使用tens…...

封装网络请求 鸿蒙APP HarmonyOS ArkTS

一、效果展示 通过在页面直接调用 userLogin(params) 方法,获取登录令牌 二、申请网络权限 访问网络时候首先需要申请网络权限,需要修改 src/main 目录下的 module.json5 文件,加入 requestPermissions 属性,详见官方文档 【声明权…...

2024年度上半年中国汽车保值率报告

来源:中国汽车流通协会&精真估 近期历史回顾: 2024上半年房地产企业数智化转型报告.pdf 2024国产院线电影路演数据洞察报告.pdf 空间数据智能大模型研究-2024年中国空间数据智能战略发展白皮书.pdf 2024年全球资产管理报告 2024年中型律师事务所的法…...

Go语言之内存分配

文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ Go 语言程序所管理的虚拟内存空间会被分为两部分:堆内…...

北京交通大学《深度学习》专业课,实验3卷积、空洞卷积、残差神经网络实验

一、实验要求 1. 二维卷积实验(平台课与专业课要求相同) ⚫ 手写二维卷积的实现,并在至少一个数据集上进行实验,从训练时间、预测精 度、Loss变化等角度分析实验结果(最好使用图表展示) ⚫ 使用torch.nn…...

WPF中UI元素继承关系

在 WPF(Windows Presentation Foundation)框架中,UI 元素是基于一个层次化的类结构构建的,这个结构以 FrameworkElement 类为核心,大多数 UI 元素都是 FrameworkElement 或其派生类的子类。FrameworkElement 类本身又继…...

qml 实现一个listview

主要通过qml实现listvie功能&#xff0c;主要包括右键菜单&#xff0c;滚动条&#xff0c;拖动改变内容等&#xff0c;c 与 qml之间的变量和函数的调用。 main.cpp #include <QQuickItem> #include <QQmlContext> #include "testlistmodel.h" int main…...

【Leetcode】十六、深度优先搜索 宽度优先搜索 :二叉树的层序遍历

文章目录 1、深度优先搜索算法2、宽度优先搜索算法3、leetcode102&#xff1a;二叉树的层序遍历4、leetcode107&#xff1a;二叉树的层序遍历II5、leetcode938&#xff1a;二叉搜索树的范围和 1、深度优先搜索算法 深度优先搜索&#xff0c;即DFS&#xff0c;从root节点开始&a…...

Ruby教程

Ruby是一种动态的、面向对象的、解释型的脚本语言&#xff0c;以其简洁和易读性而闻名。Ruby的设计哲学强调程序员的生产力和代码的可读性&#xff0c;同时也融合了功能性和面向对象编程的特性。 以下是一个基础的Ruby教程&#xff0c;涵盖了一些基本概念和语法&#xff1a; …...

react + pro-components + ts完成单文件上传和批量上传

上传部分使用的是antd中的Upload组件,具体如下: GradingFilingReportUpload方法是后端已经做好文件流,前端只需要调用接口即可 单文件上传 <Uploadkey{upload_${record.id}}showUploadList{false}accept".xlsx"maxCount{1}customRequest{({ file }) > {const …...

暑假第一周——ZARA仿写

iOS学习 前言首页&#xff1a;无限轮播图商城&#xff1a;分类我的&#xff1a;自定义cell总结 前言 结束了UI的基础学习&#xff0c;现在综合运用开始写第一个demo&#xff0c;在实践中提升。 首页&#xff1a;无限轮播图 先给出效果&#xff1a; 无限轮播图&#xff0c;顾…...

github.com/antchfx/jsonquery基本使用

要在 GitHub 上使用 antchfx/jsonquery 库来查找 JSON 文档中的元素&#xff0c;首先需要了解这个库的基本用法。jsonquery 是一个用于查询 JSON 数据的 Go 语言库&#xff0c;允许使用 XPath 表达式来查找和选择 JSON 数据中的元素。 以下是一些基本步骤和示例&#xff0c;演…...

【python虚拟环境管理】【mac m3】使用poetry管理python项目

文章目录 一. 为什么选择poetry二. poetry相关操作1. 创建并激活环境2. 依赖包管理2.1. 安装项目依赖1.2. 管理不同开发环境的依赖1.3. 依赖维护1.4. 项目相关 Poetry是Python中用于依赖管理和打包的工具。它允许您声明项目所依赖的库&#xff0c;并将为您管理&#xff08;安装…...

《JavaSE》---16.<抽象类接口Object类>

目录 前言 一、抽象类 1.1什么是抽象类 1.2抽象类代码实现 1.3 抽象类特点 1.4抽象类的作用 二、接口 2.1什么是接口 2.2接口的代码书写 2.3 接口使用 2.4 接口特点 2.5 实现多个接口 快捷键&#xff08;ctrl i &#xff09;&#xff1a; 2.6接口的好处 2.7 接…...

简单修改,让UE4/5着色器编译速度变快

简单修改&#xff0c;让UE4/5着色器编译速度变快 目录 简单修改&#xff0c;让UE4/5着色器编译速度变快 一、问题描述 二、解决方法 &#xff08;一&#xff09;硬件升级 &#xff08;二&#xff09;调整相关设置和提升优先级 1.调整相关设置 &#xff08;1&#xff09…...

AI智能体商业化实战:x402支付技能包集成指南

1. 项目概述&#xff1a;为AI智能体插上商业化的翅膀最近在折腾AI智能体&#xff08;Agent&#xff09;的落地应用&#xff0c;发现了一个挺有意思的痛点&#xff1a;怎么让这些能写代码、能处理任务的AI&#xff0c;真正地“赚到钱”&#xff1f;或者说&#xff0c;我们开发者…...

告别JSON臃肿:手把手教你用MessagePack为C++微服务瘦身(附性能对比)

告别JSON臃肿&#xff1a;手把手教你用MessagePack为C微服务瘦身&#xff08;附性能对比&#xff09; 在当今高性能后端服务开发中&#xff0c;微服务架构已成为主流选择。然而&#xff0c;随着服务规模的扩大&#xff0c;服务间通信的数据量急剧增长&#xff0c;传统的JSON序列…...

【RK3588开发】SPI回环

SPI回环 &#xff08;1&#xff09;内核SPI子系统使能 修改内核配置需要先加载默认配置&#xff0c;然后图形界面修改后需保存配置在以下目录下勾选图中的选项&#xff1a; **>**Device Drivers —> ​ ->[*] SPI support —>至少勾选以下选项&#xff1a; Rockchi…...

PyODBC:如何用Python一站式连接所有主流数据库?

PyODBC&#xff1a;如何用Python一站式连接所有主流数据库&#xff1f; 【免费下载链接】pyodbc Python ODBC bridge 项目地址: https://gitcode.com/gh_mirrors/py/pyodbc 你是否遇到过这样的困境&#xff1a;公司项目需要连接SQL Server&#xff0c;个人项目要用MySQL…...

TrollInstallerX终极指南:iOS 14-16.6.1越狱工具一键部署全解析

TrollInstallerX终极指南&#xff1a;iOS 14-16.6.1越狱工具一键部署全解析 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 想要在iOS 14.0到16.6.1系统上轻松安装Troll…...

Python使用Matplotlib绘制基础可视化图表

在Python中进行数据可视化&#xff0c;最常用且功能强大的库是 Matplotlib。它可以帮助你轻松绘制出柱状图、折线图、饼图、散点图、直方图、箱线图、热力图、雷达图等。在开始之前&#xff0c;请确保你已经安装了Matplotlib库。如果没有&#xff0c;可以在终端或命令行中运行以…...

Midjourney 8x10高保真输出崩溃诊断:内存溢出日志解析、--sref跨模型参考失效、以及GPU显存碎片化导致的upscale中断(附实时监控脚本)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney 8x10高保真输出崩溃现象全景概览 近期&#xff0c;大量 Midjourney 用户在使用 --s 1000 --q 2 --v 6.3 配合 --ar 8:10 参数生成高分辨率人像/建筑类图像时&#xff0c;遭遇高频次任务中…...

服务器运维(四十八)linux删除无用依赖 —东方仙盟

一、逐条安全性分析1. sudo dnf autoremove -y作用&#xff1a;删掉安装软件后遗留的无用依赖包风险&#xff1a;极低禁忌&#xff1a;你现在只跑 nginxmysqllua&#xff0c;没有冷门依赖&#xff0c;随便跑效果&#xff1a;清大量残留库、编译依赖2. sudo dnf clean all作用&a…...

高速数字系统中的抖动测量与分析技术详解

1. 抖动测量基础与核心概念解析在高速数字系统设计中&#xff0c;抖动&#xff08;Jitter&#xff09;已经成为影响信号完整性的关键参数。简单来说&#xff0c;抖动就是数字信号边沿相对于理想时序位置的偏差。这种时域上的微小偏移看似微不足道&#xff0c;但当数据速率突破1…...

3PEAK思瑞浦 TP2272-SO1R SOP8 精密运放

特性 增益带宽积:7MHz 高斜率:20V/us 宽电源范围:3.1V至36V或2.25V至18V 低失调电压:0.5mV(最大值) 低输入偏置电流:30pA(典型值) 轨到轨输出电压范围 单位增益稳定: 工作温度范围:-40C至125C...