inventoresed
Version:
Z-Wave driver written entirely in JavaScript/TypeScript
40 lines (37 loc) • 1.22 kB
text/typescript
export class GraphNode<T> {
public constructor(value: T, edges: Iterable<GraphNode<T>> = []) {
this.value = value;
this.edges = new Set(edges);
}
/** The value of this node */
public readonly value: T;
/** Which nodes this node depends on */
public readonly edges: Set<GraphNode<T>>;
}
/**
* Performs a topological sort of the given graph so that nodes without dependencies come first.
* Warning: This method will change the input dataset!
*/
export function topologicalSort<T>(graph: GraphNode<T>[]): T[] {
const ret: T[] = [];
while (graph.length) {
// Step 1: Find nodes without dependencies
const nodesWithoutDependencies = graph.filter(
(node) => node.edges.size === 0,
);
if (!nodesWithoutDependencies.length) {
throw new Error("Circular dependency detected!");
}
// Step 2: Move them from the input to the output
const newNodes = nodesWithoutDependencies.map((node) => node.value);
ret.push(...newNodes);
graph = graph.filter((node) => node.edges.size > 0);
// Step 3: Mark them as visited / remove from other nodes dependencies
for (const node of graph) {
for (const visited of nodesWithoutDependencies) {
node.edges.delete(visited);
}
}
}
return ret;
}