49 lines
No EOL
1.5 KiB
JavaScript
Executable file
49 lines
No EOL
1.5 KiB
JavaScript
Executable file
/**
|
|
* This examples shows how to find all connected components of a graph.
|
|
*
|
|
* Created in response to https://github.com/anvaka/ngraph.graph/issues/18
|
|
*/
|
|
module.exports = function findConnectedComponents(graph) {
|
|
var nodeIdToComponentId = new Map();
|
|
|
|
var connectedComponents = [];
|
|
var lastComponentId = 0;
|
|
|
|
graph.forEachNode(function(node) {
|
|
if (nodeIdToComponentId.has(node.id)) {
|
|
// we already seen this cluster. Ignore it.
|
|
return;
|
|
}
|
|
|
|
// We found a new connected component:
|
|
nodeIdToComponentId.set(node.id, lastComponentId);
|
|
var currentComponent = [node.id];
|
|
connectedComponents.push(currentComponent);
|
|
|
|
// Let's find what other nodes belong to this component
|
|
dfs(graph, node.id, otherNode => {
|
|
let componentId = nodeIdToComponentId.get(otherNode.id);
|
|
if (componentId !== undefined && componentId === lastComponentId) {
|
|
// this is possible when we have a loop. Just ignore the node.
|
|
return false;
|
|
} else if (componentId !== undefined) {
|
|
throw new Error('Reached a component from another component. DFS is broken?');
|
|
}
|
|
|
|
currentComponent.push(otherNode.id);
|
|
nodeIdToComponentId.set(otherNode.id, lastComponentId);
|
|
|
|
return true; // let's visit neighbors
|
|
});
|
|
|
|
lastComponentId += 1;
|
|
});
|
|
|
|
return connectedComponents;
|
|
};
|
|
|
|
function dfs(graph, startFromNodeId, visitor) {
|
|
graph.forEachLinkedNode(startFromNodeId, function(otherNode) {
|
|
if (visitor(otherNode)) dfs(graph, otherNode.id, visitor);
|
|
});
|
|
} |