当前位置: 首页 > 知识库问答 >
问题:

为什么必须为二叉树的递归插入显式设置左/右子级?

邵宜年
2023-03-14

我只是在玩一个二叉树,我很好奇为什么第一个实现有效,而第二个没有。我忽略了什么?我觉得这很琐碎,但我还是很怀念。

//just a wrapper around the insertTree method.
public void insertKey(int key){
    
    if(root==null) //a private 'Node' variable.
        root = new Node(key);
    else
        insertTree(key, root);
}

//recursive insert - working
private void insertTree(int key, Node node)
{
    if(key <= node.getKey())
    {
        if(node.left!=null)
            insertTree(key, node.left);
        else
            node.left = new Node(key); //explicitly setting left child
    }
    else
    {
        if(node.right!=null)
            insertTree(key, node.right);
        else
            node.right = new Node(key); //explicitly setting right child
    }
            
}

不起作用的变体:

private void insertTree(int key, Node node)
{  //if node is null, create a new node. Can be either node.left or node.right
       if(node==null)
       {
           node = new Node(key);
           return;
       }
       else
          if(key <= node.getKey())
             insertTree(key, node.left);
          else
             insertTree(key, node.right);
                                
}

Node只是一个简单的类,包含publicleft、right成员和一个int-key数据成员。没什么特别的。所以#1工作得很好,按序遍历产生一个排序的输出。现在#2似乎不起作用了。根是唯一被初始化的根,其左/右子级继续为空。所以如果我通过节点。左作为参数,为什么递归方法调用不为其分配新节点?我错过了什么?Java是通过引用传递的(即引用的值),所以我猜这应该是可行的,但也许我在这里遗漏了什么。

共有2个答案

景安翔
2023-03-14

您不应该使用递归向二叉树添加元素。递归涉及昂贵的隐式堆栈。只需迭代即可找到添加节点的正确位置。另外,当你使用迭代时,你不需要两种方法来完成这项工作——一种就足够了。请看以下非常简单的代码:http://www.geekviewpoint.com/java/bst/add

谢俊悟
2023-03-14

它不起作用的原因是,对insertTree的上一次递归调用中的node变量实际上并没有引用与节点相同的内存位置。在前面的通话中向左。调用函数(/method)可以有效地为堆栈上的所有参数创建新的存储位置,并在那里复制参数值。

因此,在第二个变量中,insertTree只需创建一个新的节点,并将其分配给该函数中的局部变量节点。该赋值不影响其他内存位置。然后它返回,新的节点将永远丢失。

你说“Java是通过引用传递的”,但事实并非如此。Java按值传递引用。

 类似资料:
  • 为了更灵活地编写代码,我每天都在尝试做不同的问题,但这一次却让我停滞不前。 下面的代码应该是在预序遍历中从给定的字符串建立一个二叉树。即“5 3 1 N N N 7 N N”表示下面的二叉树。元素之间用空格分隔,N标记空节点,空节点正好为NULL。 它应该像遍历拆分的字符串一样简单,当找到以外的东西时,就用该值构造一个,并增加。 增加之后,我再次将下一个数组元素放入左侧子树中。如果遇到,则不需要执

  • 堆属性说: 如果A是B的父节点,则节点A的键相对于节点B的键进行排序,并在堆中应用相同的排序。要么父节点的键总是大于或等于子节点的键,最高键在根节点(这种堆称为最大堆),要么父节点的键小于或等于子节点的键,最低键在根节点(最小堆)。 但是为什么在这个wiki中,二进制堆必须是一个完整的二叉树呢?在我的印象中,堆属性并不意味着这一点。

  • 通常我们按顺序、前顺序或后顺序遍历二叉搜索树。但是,当我们按照从右到根到左的递归顺序遍历二叉搜索树时,会发生什么呢? 假设如果我将值存储在数组中,并且与前序遍历相比,当我们按此顺序遍历时,它的时间复杂度是否会增加。

  • 我有一个btree类和一个insert函数,可以在树的宽度方向上插入节点。但树没有在右侧插入节点。 我正在创建根节点。insert函数将左、右节点正确插入根节点。 然后递归地,我尝试在左侧节点插入两个节点,在右侧节点插入两个节点。但在这一步中,所有节点仅添加到左侧。节点也会添加到无父节点。 我知道,我在插入函数中的最后一个语句中犯了一个错误。但是我尝试了很多组合,但是都导致了一些错误。

  • 我试图实现一个二叉查找树使用Java。我想创建的函数之一是删除函数。这将由两个方法组成,一个称为删除,另一个称为getNodeToDelete。getNodeToDelete方法是删除方法的辅助函数。 getNodeToDelete方法是递归的,基本上返回用户希望从树中删除的节点。使用此getNodeToDelete方法返回的节点,非递归删除方法基本上会根据不同情况(例如,它是叶节点还是根节点等)