繁体   English   中英

图遍历(图中的源节点和目标节点之间是否存在连接) - 访问过的 DFS 与 BFS

[英]Graph Traversal (is there a connection between source and destination nodes in the graph) - visited DFS vs BFS

我不了解潜在的循环图遍历,为什么图中的源节点和目标节点之间存在连接:

i) DFS,如果一个节点被访问,我们返回 false

ii) BFS,如果一个节点被访问,我们继续(在循环中)

示例代码(来自https://structy.net/problems/undirected-path ):

const undirectedPath = (edges, nodeA, nodeB) => {
  const graph = buildGraph(edges);
  return hasPath(graph, nodeA, nodeB, new Set());
}

// BFS
const hasPath = (graph, src, dst, visited) => {
  const queue = [src];
  
  while(queue.length > 0){
    const current = queue.shift();
    if(current === dst) return true;
    // if it's DFS, do not "continue", instead "return false" - why?
    if(visited.has(current)) continue;
    visited.add(current);
    for(let neighbor of graph[current]){
      queue.push(neighbor);
    }
  }
  return false;
}

const buildGraph = (edges) => {
  const graph = {}; 
  for(let edge of edges){
    const[a, b] = edge;
    if(!(a in graph)) graph [a] = [];
    if(!(b in graph)) graph [b] = [];
    graph[a].push(b);
    graph[b].push(a);
  }
  return graph;
}

const edges = [
  ['i', 'j'],
  ['k', 'i'],
  ['m', 'k'],
  ['k', 'l'],
  ['o', 'n']
];

undirectedPath(edges, 'j', 'm'); // -> true

考虑一个有两个节点的简单图:

  • A(开始)
  • B(目标)

也有两个边缘:

  • A->A
  • A->B

在您的 DFS 方法中,您有以下步骤

  • 从堆栈中弹出一个当前节点,这会给你 A
  • 它不是目的地,也没有被访问过,所以你把它添加到访问过的节点列表中
  • 您现在将邻居添加到堆栈中,即 A 和 B
  • 下一次迭代,你从堆栈中弹出另一个当前节点,这再次给你 A
  • 它已经被访问过,所以你返回 false,即使路径存在

简而言之,您的算法有问题。 请注意,这甚至不需要边缘循环自身的特殊情况。 所需要的只是一个在达到目标之前评估的循环。 此外,如果碰巧首先检查了邻居 B,您将得到正确的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM