【问题标题】:Issues with Binary TreeNode editing function二叉树节点编辑功能的问题
【发布时间】:2019-07-04 14:08:42
【问题描述】:

我的代码有问题。

此函数的目的是遍历二叉树并对其进行编辑,以便将某个点的分支替换为“newNode”下的新分支。目前,它为它开始的树返回相同的值(因此current = newNode 实际上并没有编辑原始树)。

谁能解释这是为什么?谢谢。

 public static Node editTree(Node current, Node newNode, String value) {
        if (current == null) {
            return null;
        }

        if (current.value.equals(value)) {
            current = newNode;
            return current;
        }

        if (!current.isLeaf()) {
            editTree(current.getLeft(), newNode, value);
            editTree(current.getRight(), newNode, value);
            return current;
        }

        return current;
    }

这必须以这样一种方式完成,即首先遍历一棵树(原始树),直到找到某个值。然后存放值的节点被一个新节点完全替换,新节点包含自己的值和自己的左右节点。然后将全局变量 Node 设置为等于新编辑的树的值,然后将其用于重置原始树的值。不能以任何其他方式完成的原因是因为我不能在节点类中设置左右节点的值,因为这是不允许的。

【问题讨论】:

  • 这不是 BST
  • 另一个可能的错误来源:if (current.value == value)- 你应该检查相等性,而不是身份 (if (current.value.equals(value)))
  • 对函数的执行方式没有影响,我已经编辑了相同的函数,因此 1) 它没有 isLeaf() 检查,2) 每次比较都使用 .equals() 和 3) 它回报较少。到目前为止,还没有产生想要的结果。
  • 是的,Kartik 在他的回答中概述了原因。但是,您还应该修复上述条件,否则您可能永远不会进入该分支并返回新的current
  • 我已经修改过了,但还是不知道怎么解决...

标签: java binary-tree nodes treenode


【解决方案1】:

current = newNode; 行中,您只是在方法中更改current 变量的引用。它不会影响原始树。您需要将newNode 设置为value 到上一个节点。

欲了解更多信息,请参阅Is Java “pass-by-reference” or “pass-by-value”?

【讨论】:

  • 我做不到。原始节点类不允许您向任何节点添加任何左或右节点,它只允许您编辑实际值(这是一个字符串),因此编辑树的唯一方法是创建另一棵树和使用上面的函数编辑那个,然后将旧树设置为等于新树。
【解决方案2】:

current 分配一个新值不会在方法之外产生任何影响。我认为你应该使用返回值:

public static Node editTree(Node current, Node newNode, String value) {
        if (current == null) {
            return null;
        }

        if (current.value.equals(value)) {
            return newNode;
        }

        if (!current.isLeaf()) {
            current.setLeft(editTree(current.getLeft(), newNode, value));
            current.setRight(editTree(current.getRight(), newNode, value));
        }

        return current;
    }

更新:完整代码和测试结果

public class Node {
    public final String value;
    private Node left;
    private Node right;

    Node(String value, Node left, Node right) {
        this.value = value;
        this.left = left;
        this.right = right;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    public boolean isLeaf() {
        return left == null && right == null;
    }

    @Override
    public String toString() {
        return "Node{" + "value=" + value + ", left=" + left + ", right=" + right + '}';
    }
}

测试方法:

public static void main(String[] args) {
    Node tree = new Node("b",
            new Node("a", null, null), new Node("c", null, null));
    System.out.println(tree);
    tree = editTree(tree, new Node("d", null, null), "c");
    System.out.println(tree);
}

结果:

Node{value=b, left=Node{value=a, left=null, right=null}, right=Node{value=c, left=null, right=null}}
Node{value=b, left=Node{value=a, left=null, right=null}, right=Node{value=d, left=null, right=null}}

【讨论】:

  • 这只会返回 newNode ......我试图返回一个现在包含 newNode 的完全编辑的树,而不仅仅是 newNode (我作为参数传递给函数第一名)
  • @TrojanTheHorse 这正是它所做的(因为该方法是递归的)
  • @TrojanTheHorse 是什么让你这么认为?
  • 好吧,一方面,我可以阅读代码,发现它不起作用。第二,为了逗你开心,我修改了代码,使它现在与你的相同,并且它的性能与以前完全一样。
  • @TrojanTheHorse 好吧,也许你需要眼镜。查看我的更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-22
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多