UNPKG

dist-javascript-algorithms-and-data-structures

Version:

Algorithms and data-structures implemented on JavaScript

67 lines (55 loc) 2.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = detectUndirectedCycle; var _depthFirstSearch = _interopRequireDefault(require("../depth-first-search/depthFirstSearch")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Detect cycle in undirected graph using Depth First Search. * * @param {Graph} graph */ function detectUndirectedCycle(graph) { let cycle = null; // List of vertices that we have visited. const visitedVertices = {}; // List of parents vertices for every visited vertex. const parents = {}; // Callbacks for DFS traversing. const callbacks = { allowTraversal: ({ currentVertex, nextVertex }) => { // Don't allow further traversal in case if cycle has been detected. if (cycle) { return false; } // Don't allow traversal from child back to its parent. const currentVertexParent = parents[currentVertex.getKey()]; const currentVertexParentKey = currentVertexParent ? currentVertexParent.getKey() : null; return currentVertexParentKey !== nextVertex.getKey(); }, enterVertex: ({ currentVertex, previousVertex }) => { if (visitedVertices[currentVertex.getKey()]) { // Compile cycle path based on parents of previous vertices. cycle = {}; let currentCycleVertex = currentVertex; let previousCycleVertex = previousVertex; while (previousCycleVertex.getKey() !== currentVertex.getKey()) { cycle[currentCycleVertex.getKey()] = previousCycleVertex; currentCycleVertex = previousCycleVertex; previousCycleVertex = parents[previousCycleVertex.getKey()]; } cycle[currentCycleVertex.getKey()] = previousCycleVertex; } else { // Add next vertex to visited set. visitedVertices[currentVertex.getKey()] = currentVertex; parents[currentVertex.getKey()] = previousVertex; } } }; // Start DFS traversing. const startVertex = graph.getAllVertices()[0]; (0, _depthFirstSearch.default)(graph, startVertex, callbacks); return cycle; }