Last active
May 7, 2020 15:42
-
-
Save DimitryDushkin/9270864096298d5e7116a91f8d5a3f29 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const makeReverseGraph = (graph: Graph): Graph => { | |
const reverseGraph: Graph = new Map(); | |
for (const [id, parentId] of dfs(graph, { withParentId: true })) { | |
const prerequesitions = reverseGraph.get(id) ?? new Set(); | |
if (parentId) { | |
prerequesitions.add(parentId); | |
} | |
reverseGraph.set(id, prerequesitions); | |
} | |
return reverseGraph; | |
}; | |
/** | |
* Iterate over every node. | |
* If withParentId = true, than it is possible to visit same not more then once | |
* @yields {[string, string?]} [nodeId, parentNodeId?] | |
*/ | |
export function* dfs( | |
graph: Graph, | |
options: { withParentId: boolean } = { withParentId: false } | |
): Generator<readonly [string, string?], void, void> { | |
const visited = new Set<ID>(); | |
// DFS interative | |
// iterate over all nodes in case of disconnected graph | |
for (const node of graph.keys()) { | |
if (visited.has(node)) { | |
continue; | |
} | |
const stack: ID[] = [node]; | |
while (stack.length > 0) { | |
const currentNode = stack.pop(); | |
assertIsDefined(currentNode); | |
yield [currentNode]; | |
visited.add(currentNode); | |
const dependencies = graph.get(currentNode); | |
if (!dependencies) { | |
continue; | |
} | |
for (const dependencyId of dependencies) { | |
if (options.withParentId) { | |
// possible to yield same nodeId multiple times (needed for making reverse graph) | |
yield [dependencyId, currentNode]; | |
} | |
if (visited.has(dependencyId)) { | |
continue; | |
} | |
stack.push(dependencyId); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment