使用 JavaScript DFS 进行拓扑排序
有向图的拓扑排序或拓扑排序是其顶点的线性排序,对于从顶点 u 到顶点 v 的有向边 UV,在排序中 u 位于 v 之前。这仅在有向图中才有意义。
拓扑排序很有用的地方很多。例如,假设你正在按照食谱制作菜肴,其中有一些步骤是转到下一步的必经步骤。但其中一些步骤可以并行执行。类似地,在大学选课时,一些高级课程有一些先修课程,这些先修课程本身可能是更高级课程的先修课程。例如 −
示例
/** * CS101 CS102 * / \ / * CS204 CS340 * \ /| \ * CS380 | CS410 * \ | / * CS540 */
在上图中,考虑是否要学习一个级别的课程,首先必须学习与它相连的所有上述级别的课程。以下是上图的一些可能的拓扑排序 −
CS101 -> CS204 -> CS102 -> CS340 -> CS410 -> CS380 -> CS540 CS102 -> CS101 -> CS340 -> CS204 -> CS410 -> CS380 -> CS540
让我们用 JavaScript 来实现这一点。我们会编写 2 个函数,即拓扑排序和拓扑排序助手,以帮助递归地标记和探索图表。
示例
topologicalSortHelper(node, explored, s) {
explored.add(node);
// Marks this node as visited and goes on to the nodes
// that are dependent on this node, the edge is node ----> n
this.edges[node].forEach(n => {
if (!explored.has(n)) {
this.topologicalSortHelper(n, explored, s);
}
});
// All dependencies are resolved for this node, we can now add
// This to the stack.
s.push(node);
}
topologicalSort() {
// Create a Stack to keep track of all elements in sorted order
let s = new Stack(this.nodes.length);
let explored = new Set();
// For every unvisited node in our graph, call the helper.
this.nodes.forEach(node => {
if (!explored.has(node)) {
this.topologicalSortHelper(node, explored, s);
}
});
while (!s.isEmpty()) {
console.log(s.pop());
}
}您可以使用以下代码进行测试 −
示例
let g = new Graph();
g.addNode("A");
g.addNode("B");
g.addNode("C");
g.addNode("D");
g.addNode("E");
g.addNode("F");
g.addNode("G");
g.addDirectedEdge("A", "C");
g.addDirectedEdge("A", "B");
g.addDirectedEdge("A", "D");
g.addDirectedEdge("C", "D");
g.addDirectedEdge("D", "E");
g.addDirectedEdge("E", "F");
g.addDirectedEdge("B", "G");
g.topologicalSort();我们创建的图表如下 −
示例
/** * A * / | \ * C | B * \ | | * D G * | * E * | * F */
输出
这会显示以下输出 −
A B G C D E F
广告
数据结构
网络
RDBMS
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP