1

我对二叉树和图中的 DFS 感到困惑。在我的理解中,二叉树的 DFS 类似于 PreOrder 遍历?图中的 DFS 有很大不同吗?请帮助在二叉树和 DFS 中澄清这个概念。我知道在二叉树中,我们可以像这样进行 DFS:

public static List<int> postorder(TreeNode root)
{
    List<int> res = new List<int>();
    traverse1(root, res);
    return res;
}

public static void traverse1(TreeNode root, List<int> res)
{
    if (root == null)
        return;    

    traverse1(root.left, res);             
    traverse1(root.right, res);
    res.Add(root.val); 
}

图中呢?我们可以这样做吗?

4

3 回答 3

3

基本上是一样的。

为了帮助理解,我认为最好从二叉树过渡到通用树,最后再过渡到图。

DFS 和 BFS 只是遍历树和图的技术。它们之间的区别在于访问给定节点的兄弟姐妹和子节点的顺序。在 DFS 中,在遍历下一个兄弟节点之前访问给定节点的所有子节点。

所以在二叉树中,这意味着在访问 X 的右孩子之前,先访问节点 X 的左孩子的所有后代。

现在,如果您考虑一般的树,每个节点都有一个子节点列表,而不仅仅是左右子节点。所以在一般树中的 DFS 中,节点 X 的第一个孩子的所有后代在访问 X 的第二个孩子之前被访问,并且 X 的第二个孩子的所有后代在访问 X 的第三个孩子之前被访问,并且很快。

DFS 和树的问题是,你知道你最终会碰到一片叶子,并且递归将返回给调用者(或因堆栈溢出而停止,但这是另一个主题)。使用图表,您没有这种保证。该图可能有循环,或者可能有带有多个传入边的顶点。正如我之前提到的,DFS 只是一种技术,而不是算法本身,所以你要做的就是让技术适应你正在解决的问题。如果在您要解决的问题中,您对多次访问一个顶点不感兴趣,或者您对在一个循环中无限期地迭代不感兴趣(或者直到您遇到堆栈溢出),那么您必须添加某种控制代码这使您可以摆脱这些情况。

图上 DFS 的一般结构可能类似于:

void DFS(G<V,E> g, V v, Set<V> visited)
{
    if (visited.Contains(v))
        return;
    visited.Add(v);
    // do something interesting here?
    foreach (w in g.getEdges(v))
        DFS(g, w, visited);
    // uncomment this to allow visiting vertices more than once, and just avoid cycles.
    // visited.Remove(v);
}
于 2015-12-01T23:32:18.010 回答
1

不,深度拳头搜索(DFS)前序遍历是不一样的。

这些概念与图论和二叉树相互关联,因为二叉树/树结构是图结构的特例

在此处输入图像描述

我们在图/树中有两种遍历

  • 深度优先遍历(DFS)(也称为级别顺序遍历)
  • 广度优先遍历 (BFS)

在广度优先遍历(BFS)下,我们有

  • 预购(访问订单根->左子树->右子树)

  • 按顺序(访问顺序左子树->根->右子树)

  • 发布顺序(访问顺序左子树 -> 右子树 -> 根)

希望这能解决您对 DFS 和预购的困惑。

DFS 表示逐级完成节点。意思是访问0级节点。然后访问1级节点,依此类推。根据图像,DFS 将是A,B,C,D,E,F,G,H,I

前序是指,首先从一个节点开始,然后遍历它的左子树,然后遍历它的右子树。如果左子树有一个节点,则访问其左子树,然后访问其右子树,依此类推。所以前序遍历将是A,B,D,E,H,I,C,F,G

DFS 与预购不同。

在此博客上查看更多信息http://goo.gl/gR4oWp

这也有很好的解释。 https://www.youtube.com/watch?v=gm8DUJJhmY4

于 2015-12-17T16:35:35.720 回答
1

图中的 DFS 和二叉树中的 DFS 看起来不同,但本质上它们是相同的。如果您记录节点并检查它们,您将看到相似性。

于 2021-04-25T02:48:04.683 回答