使用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中實現它。我們將編寫兩個函式:拓撲排序和topologicalSortHelper來幫助遞迴地標記和探索圖。
示例
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