如何从指定对象中找出所有可行遍历路径?我用while循环未找到正确逻辑
如何找出有向无环图中从起点到终点的所有路径?
嘿,这个问题其实是典型的有向无环图(DAG)中寻找从起点到终点的所有路径的场景,用while循环的话确实容易在处理分支路径的时候卡壳——毕竟每次遇到多个子节点时,得保存当前的路径状态,再分别去探索每个分支才行。我给你两种实用的实现思路,递归DFS和迭代DFS(也就是你想用的while循环方式),都能完美解决这个问题:
先明确你的输入和预期输出:
// 输入的图结构 const pathObject = { A :["B"], B :["C", "D"], D :["E"], C :["F", "E"], E :["G"], F :["G"], G :["H"], H :[] }; // 预期输出 // [ ["A", "B", "C", "F", "G", "H"], ["A", "B", "D", "E", "G", "H"], ["A", "B", "C", "E", "G", "H"] ]
方法一:递归深度优先搜索(DFS)
递归的思路非常直观:从起点A出发,每次遍历当前节点的所有子节点,把当前节点加入路径,直到走到没有子节点的终点H,就把完整路径存入结果数组。
function findAllPaths(graph, start, end) { const result = []; function dfs(currentNode, currentPath) { // 复制当前路径并加入当前节点,避免分支间路径互相干扰 const newPath = [...currentPath, currentNode]; // 到达终点,保存路径并终止当前分支探索 if (currentNode === end) { result.push(newPath); return; } // 遍历所有子节点,递归探索每个分支 for (const neighbor of graph[currentNode]) { dfs(neighbor, newPath); } } dfs(start, []); return result; } // 调用示例 console.log(findAllPaths(pathObject, "A", "H")); // 输出完全符合你的预期结果
方法二:迭代DFS(用while循环实现)
如果你更倾向于用while循环,本质就是用栈来模拟递归的过程。栈里的每个元素要同时保存当前节点和当前的路径,这样每次弹出栈元素时,就能继续探索它的子节点,同时不会丢失之前的路径信息。
function findAllPathsIterative(graph, start, end) { const result = []; // 栈中存储格式:[当前节点, 当前已走路径] const stack = [[start, [start]]]; while (stack.length > 0) { const [currentNode, currentPath] = stack.pop(); // 到达终点,直接保存路径 if (currentNode === end) { result.push(currentPath); continue; } // 倒序遍历子节点入栈,保证输出顺序和递归版本一致(可选操作) for (let i = graph[currentNode].length - 1; i >= 0; i--) { const neighbor = graph[currentNode][i]; // 复制路径并加入新节点,入栈等待探索 stack.push([neighbor, [...currentPath, neighbor]]); } } return result; } // 调用示例 console.log(findAllPathsIterative(pathObject, "A", "H")); // 同样得到你想要的结果
为啥单纯用while循环容易卡壳?
如果只是简单的遍历节点而不保存每个分支的路径状态,就会丢失之前的路径信息——比如走到B节点时,要同时探索C和D两个分支,这时候得把["A","B"]这个路径分别复制给两个分支,再各自往下走。用栈保存每个节点对应的路径,就能完美解决这个分支保存的问题。
内容的提问来源于stack exchange,提问作者Akbar Basha
相关产品推荐
相关产品推荐

