【问题标题】:Traversing a Binary Tree Recursively递归遍历二叉树
【发布时间】:2012-04-12 03:50:01
【问题描述】:

当谈到递归函数时,我完全迷失了方向。我需要创建一个递归函数来遍历二叉树并在特定值之间插入一个新节点。我是否需要重新复制我的遍历函数并在我使用它的所有其他函数中修改它?有人可以评估一下遍历功能吗?

我觉得我的遍历代码没问题。

Node traverse (Node currentNode){
    if (!currentNode.left.equals(null)){
        traverse (currentNode.left);
        return currentNode.left;
    }
    if (!currentNode.right.equals(null)){
        traverse (currentNode.right);
        return currentNode.right;
    }
    return currentNode;
}

【问题讨论】:

  • traverse 方法用于使用二叉树中的元素,但您返回的是左根、右根或根(即使根是null!)。递归函数的想法是定义基本情况,然后定义重复代码直到该基本情况
  • 您要进行什么样的遍历?是BST 吗?是否需要在BST 的正确位置插入节点?
  • 如果您向左遍历,您将作为第 4 行的最后一步返回,并且永远不会向右遍历,并且永远不会返回 currentNode。看起来不太好。
  • 具体值在哪里?你的函数看起来几乎像一个预序遍历,但由于不清楚它应该做什么,所以无法评估它实现它的效果。

标签: java binary-tree


【解决方案1】:

对于二叉树,有几种不同类型的遍历可以递归完成。它们按照引用然后访问的顺序编写(L=左孩子,V = 访问该节点,R = 右孩子)。

  • 中序遍历 (LVR)
  • 逆序遍历 (RVL)
  • 前序遍历 (VLR)
  • 后序遍历 (LRV)

您的代码似乎正在执行后序遍历方法,但您弄混了一些东西。首先,节点就是你要遍历的; data 是您要访问的内容。其次,您没有理由以实现方式返回节点本身。您的代码不允许有条件说“我正在寻找 this 特定数据,您有 Node@0xdeadbeef 先生吗?”,这会与某种额外的搜索参数。

学术 BST 遍历仅打印节点本身。如果您想添加搜索功能,只需多一个参数,以及对正确节点的额外检查。

这是一个sn-p:

// Academic

public void traverse (Node root){ // Each child of a tree is a root of its subtree.
    if (root.left != null){
        traverse (root.left);
    }
    System.out.println(root.data);
    if (root.right != null){
        traverse (root.right);
    }
}

// Search with a valid node returned, assuming int

public Node traverse (Node root, int data){ // What data are you looking for again?
    if(root.data == data) {
        return root;
    }
    if (root.left != null && data < root.data) {
        return traverse (root.left, data);
    }
    if (root.right != null && data > root.data) {
        return traverse (root.right, data);
    }
    return null;
}

【讨论】:

  • 谢谢。我不知道自己在做什么。
  • 对于搜索示例,第一次递归调用应检查结果是否为空,然后仅检查右侧是否为空。否则,如果搜索值位于最左下角的节点中,它将仅返回结果。公共节点遍历(节点根,int数据){if(root.data ==数据){返回根; } if (root.left != null){ Node val = traverse (root.left, data); if(val != null){ return val; } else if (root.right != null){ return traverse (root.right, data); } } 返回空值; }
  • @Aaron 我不同意。
  • 如果在最左边的分支中没有找到数据,答案中的算法将返回“null”,然后它会将结果一直冒泡到顶部,即使数据位于某个地方其他在树上。没有任何步骤可以迫使它走上“正确”的道路。看到这个答案stackoverflow.com/a/5938541/572166
  • 嗯。我明白你现在的意思了@Aaron。我会调整这个。
【解决方案2】:

您似乎正在遍历预购方法,但我有点怀疑您究竟希望完成什么而不实际将您的当前节点与一些定义您已到达目的地的基本值进行比较。我建议画出一棵简单的树并可视化这些步骤。然后尝试将其放入代码中。

【讨论】:

  • 没错。把它画在纸上,先了解一下步骤。然后在你的代码中插入打印语句,这样你就可以看到每一步实际发生了什么。一旦你了解了递归的概念,它就不是那么难了。
【解决方案3】:

递归函数通过修改的参数或终止(退出)条件返回自身的值。例如,阶乘:

int factorial( int param ) {
   if ( param > 1 ) {
      return param * factorial( param -1 );
   } else {
      return 1;
   }
}

在您的代码中,您调用了“遍历”,然后对结果不执行任何操作... 当您的递归函数结束时,您的最终返回将是第一个左孩子(如果存在),否则是第一个右孩子(如果存在),否则是根节点。

请详细说明为什么需要遍历树(另外,不确定“复制函数并在每个其他函数中修改它”是什么意思,函数的整个想法是一次编码 -呼叫多)

【讨论】:

    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 2013-07-23
    • 2021-07-26
    • 1970-01-01
    • 2020-09-25
    相关资源
    最近更新 更多