如何移除DFS路径中的死胡同节点 仅保留起点到终点的有效路径
问题说明
执行现有DFS代码时,console.log会输出大量冗余节点。需求为仅获取从起点到终点的必需路径节点(无需为最短路径),剔除算法找到正确路径前遍历的所有无效路径、无效节点。
现有实现代码:
function dfs(start, visited = new Set()) { console.log(start) visited.add(start); const destinations = adjacencyList.get(start); for (const destination of destinations) { if (destination === 'BKK') { console.log(`DFS found Bangkok`) return; } if (!visited.has(destination)) { dfs(destination, visited); } } } dfs('PHX')
问题根因
现有代码的逻辑缺陷直接导致冗余输出:
- 遍历到任意节点就立刻打印、加入已访问集合,没有判断该节点是否最终处于通往终点的有效路径上
- 命中终点后直接return,没有回溯逻辑,无法剔除探索错误分支时加入的无效节点
修复实现
通过路径回溯+递归返回值标记的方式即可实现需求:用数组维护当前递归探索的路径,递归下探时如果子分支无法抵达终点,就把当前节点从路径中弹出;如果子分支命中终点,就直接返回真值截断后续无效遍历,最终留存的路径数组就是无冗余的有效通路。
修复后代码:
function dfs(start, end, visited = new Set(), path = []) { // 标记当前节点已访问,加入当前探索路径 visited.add(start); path.push(start); // 命中终点,向上返回找到路径的标记 if (start === end) { return true; } const destinations = adjacencyList.get(start); for (const destination of destinations) { if (!visited.has(destination)) { // 子分支找到终点的话,直接向上透传成功标记,不再遍历剩余分支 if (dfs(destination, end, visited, path)) { return true; } } } // 所有邻接节点都无法抵达终点,当前节点属于无效分支,回溯弹出 path.pop(); return false; } // 调用方式 const finalPath = []; dfs('PHX', 'BKK', new Set(), finalPath); console.log(finalPath); // 按顺序输出从PHX到BKK的有效路径节点,无冗余 console.log('DFS found Bangkok');
实现说明
- 最终
finalPath数组中仅保留从起点到终点的通路节点,所有探索死路时遍历到的无效节点都会在回溯阶段被剔除 - 找到第一条可达终点的路径后就会终止遍历,符合“不需要最短路径”的需求
- 保留原有的visited集合逻辑,避免图中存在环时出现递归死循环
内容的提问来源于stack exchange,提问作者Mateo Covacho
相关产品推荐
相关产品推荐

