62 lines
1.7 KiB
JavaScript
62 lines
1.7 KiB
JavaScript
|
(function (exports) {
|
||
|
'use strict';
|
||
|
|
||
|
var topologicalSort = (function () {
|
||
|
|
||
|
function topologicalSortHelper(node, visited, temp, graph, result) {
|
||
|
temp[node] = true;
|
||
|
var neighbors = graph[node];
|
||
|
for (var i = 0; i < neighbors.length; i += 1) {
|
||
|
var n = neighbors[i];
|
||
|
if (temp[n]) {
|
||
|
throw new Error('The graph is not a DAG');
|
||
|
}
|
||
|
if (!visited[n]) {
|
||
|
topologicalSortHelper(n, visited, temp, graph, result);
|
||
|
}
|
||
|
}
|
||
|
temp[node] = false;
|
||
|
visited[node] = true;
|
||
|
result.push(node);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Topological sort algorithm of a directed acyclic graph.<br><br>
|
||
|
* Time complexity: O(|E| + |V|) where E is a number of edges
|
||
|
* and |V| is the number of nodes.
|
||
|
*
|
||
|
* @public
|
||
|
* @module graphs/others/topological-sort
|
||
|
* @param {Array} graph Adjacency list, which represents the graph.
|
||
|
* @returns {Array} Ordered vertices.
|
||
|
*
|
||
|
* @example
|
||
|
* var topsort =
|
||
|
* require('path-to-algorithms/src/graphs/' +
|
||
|
* 'others/topological-sort').topologicalSort;
|
||
|
* var graph = {
|
||
|
* v1: ['v2', 'v5'],
|
||
|
* v2: [],
|
||
|
* v3: ['v1', 'v2', 'v4', 'v5'],
|
||
|
* v4: [],
|
||
|
* v5: []
|
||
|
* };
|
||
|
* var vertices = topsort(graph); // ['v3', 'v4', 'v1', 'v5', 'v2']
|
||
|
*/
|
||
|
return function (graph) {
|
||
|
var result = [];
|
||
|
var visited = [];
|
||
|
var temp = [];
|
||
|
for (var node in graph) {
|
||
|
if (!visited[node] && !temp[node]) {
|
||
|
topologicalSortHelper(node, visited, temp, graph, result);
|
||
|
}
|
||
|
}
|
||
|
return result.reverse();
|
||
|
};
|
||
|
}());
|
||
|
|
||
|
exports.topologicalSort = topologicalSort;
|
||
|
|
||
|
}(typeof exports === 'undefined' ? window : exports));
|