图的DFS。。类似树的DFS
Depth-First Search (DFS)
Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data structures. One starts at the root (selecting some arbitrary node as the root in the case of a graph) and explores as far as possible along each branch before backtracking.
判断连通性代码:
const allowTraversalCallback = ( () => { const seen = {}; return ({ nextVertex }) => {//如果没有访问过邻近结点,则返回true if (!seen[nextVertex.getKey()]) { seen[nextVertex.getKey()] = true; return true; } return false; }; } )();
完整代码:
/** * @typedef {Object} Callbacks * * @property {function(vertices: Object): boolean} [allowTraversal] - * Determines whether DFS should traverse from the vertex to its neighbor * (along the edge). By default prohibits visiting the same vertex again. * * @property {function(vertices: Object)} [enterVertex] - Called when DFS enters the vertex. * * @property {function(vertices: Object)} [leaveVertex] - Called when DFS leaves the vertex. */ /** * @param {Callbacks} [callbacks] * @returns {Callbacks} */ function initCallbacks(callbacks = {}) {//对回调函数进行初始化 const initiatedCallback = callbacks; const stubCallback = () => {}; const allowTraversalCallback = ( () => { const seen = {}; return ({ nextVertex }) => {//如果没有访问过邻近结点,则返回true if (!seen[nextVertex.getKey()]) { seen[nextVertex.getKey()] = true; return true; } return false; }; } )(); initiatedCallback.allowTraversal = callbacks.allowTraversal || allowTraversalCallback; initiatedCallback.enterVertex = callbacks.enterVertex || stubCallback; initiatedCallback.leaveVertex = callbacks.leaveVertex || stubCallback; return initiatedCallback; } /** * @param {Graph} graph * @param {GraphVertex} currentVertex * @param {GraphVertex} previousVertex * @param {Callbacks} callbacks */ function depthFirstSearchRecursive(graph, currentVertex, previousVertex, callbacks) { callbacks.enterVertex({ currentVertex, previousVertex }); graph.getNeighbors(currentVertex).forEach((nextVertex) => { if (callbacks.allowTraversal({ previousVertex, currentVertex, nextVertex })) { depthFirstSearchRecursive(graph, nextVertex, currentVertex, callbacks); } }); callbacks.leaveVertex({ currentVertex, previousVertex }); } /** * @param {Graph} graph * @param {GraphVertex} startVertex * @param {Callbacks} [callbacks] */ export default function depthFirstSearch(graph, startVertex, callbacks) { const previousVertex = null; depthFirstSearchRecursive(graph, startVertex, previousVertex, initCallbacks(callbacks)); }