JavaScript 拓扑排序

· 约 6 分钟读完 · 第 98 / 105 章

拓扑排序是一种用于有向无环图(DAG, Directed Acyclic Graph)的线性排序。它常被用来确定一个任务或事件在其他依赖任务完成后才能执行的顺序。在本章中,我们将探讨如何使用 JavaScript 来实现拓扑排序。

什么是拓扑排序?

拓扑排序是一个顶点序列,使得对于任何一条从顶点 u 到顶点 v 的有向边,在序列中顶点 u 总是在顶点 v 之前出现。如果图中存在环,则不存在拓扑排序。

拓扑排序的应用场景

  • 项目管理:确定项目中各项任务的执行顺序。
  • 编译器:在编译过程中决定源代码文件的编译顺序。
  • 课程安排:在大学或学院中决定课程的选修顺序。

图的基本概念

在开始实现拓扑排序之前,我们需要了解一些基本的图论概念:

  • 顶点(Vertex):图中的节点。
  • 边(Edge):连接两个顶点的连线。
  • 入度(In-degree):指向某个顶点的边的数量。
  • 出度(Out-degree):从某个顶点出发的边的数量。
  • 有向图(Directed Graph):边有方向的图。
  • 无向图(Undirected Graph):边没有方向的图。
  • 有向无环图(DAG):没有环的有向图。

实现拓扑排序

实现拓扑排序有两种常见方法:基于深度优先搜索(DFS)和基于广度优先搜索(BFS)。我们将分别介绍这两种方法。

基于深度优先搜索(DFS)

数据结构

首先,我们需要定义一个数据结构来表示图。这里我们使用邻接表的形式:

DFS 实现

接下来是 DFS 的实现。我们需要一个辅助栈来存储排序结果,并且需要一个数组来记录顶点是否已经被访问过。

基于广度优先搜索(BFS)

BFS 实现

基于 BFS 的拓扑排序通常使用 Kahn 算法。Kahn 算法的核心思想是不断移除入度为 0 的顶点,并将其加入结果队列,直到所有顶点都被处理完。

总结

在这一章中,我们学习了拓扑排序的概念及其应用场景,并详细介绍了两种实现拓扑排序的方法:基于 DFS 和基于 BFS(Kahn 算法)。通过这些方法,我们可以有效地对有向无环图进行排序,从而解决许多实际问题。希望这些知识能帮助你在前端开发中更好地理解和应用图算法。