Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/algorithms/graph/detect-cycle/detectUndirectedCycle.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import depthFirstSearch from '../depth-first-search/depthFirstSearch';
* Detect cycle in undirected graph using Depth First Search.
*
* @param {Graph} graph
* @return {Object|null} - cycle object or null if no cycle detected.
* The cycle object has vertex keys as properties and parent vertices as values,
* representing the mapping of each vertex in the cycle to its predecessor.
*/
export default function detectUndirectedCycle(graph) {
let cycle = null;
Expand All @@ -18,19 +21,22 @@ export default function detectUndirectedCycle(graph) {
const callbacks = {
allowTraversal: ({ currentVertex, nextVertex }) => {
// Don't allow further traversal in case if cycle has been detected.
// This provides an early exit once a cycle is found, avoiding
// unnecessary traversal of the remaining graph.
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.
// The cycle is represented as an object where each key is a vertex
// in the cycle and its value is the previous vertex in the path.
cycle = {};

let currentCycleVertex = currentVertex;
Expand All @@ -51,7 +57,9 @@ export default function detectUndirectedCycle(graph) {
},
};

// Start DFS traversing.
// Start DFS traversing from the first vertex.
// Note: For disconnected graphs, this will only detect cycles in the
// component containing the first vertex.
const startVertex = graph.getAllVertices()[0];
depthFirstSearch(graph, startVertex, callbacks);

Expand Down