Java 反转/镜像二叉树。方法没有保持输入树不变吗?

Java 反转/镜像二叉树。方法没有保持输入树不变吗?,java,tree,pass-by-reference,Java,Tree,Pass By Reference,我是Java新手,只做了一个月的编程,所以我一直在练习一些概念。所以,如果这是一个幼稚或愚蠢的问题,请耐心等待我。我以前只在MATLAB中编程过 我在第一次尝试时也成功地反转了一个二叉树!。然而,我一直在苦苦思索,为什么我的方法实际上是修改作为输入传递的树,而不是让它保持原样,只返回一个倒置的变量。简而言之,在我的主函数中的以下行之后: 反向=反向二进制TreeRoot “inverse”和“root”都是相等的,在我将“root”传递到方法“inverseBaryTree”之前,它们是“roo

我是Java新手,只做了一个月的编程,所以我一直在练习一些概念。所以,如果这是一个幼稚或愚蠢的问题,请耐心等待我。我以前只在MATLAB中编程过

我在第一次尝试时也成功地反转了一个二叉树!。然而,我一直在苦苦思索,为什么我的方法实际上是修改作为输入传递的树,而不是让它保持原样,只返回一个倒置的变量。简而言之,在我的主函数中的以下行之后:

反向=反向二进制TreeRoot

“inverse”和“root”都是相等的,在我将“root”传递到方法“inverseBaryTree”之前,它们是“root”的反转版本。求你了,我在试图理解这种行为的时候都疯了

事实上,我甚至尝试创建一个辅助方法“invertBinaryTree2”,这个变量将输入复制到占位符节点,并在占位符节点上操作,而不是在输入上操作;然而,这并没有帮助,我的输入仍然保持不变

这是我的第一个完整的主函数和支持函数。invertBinaryTree和invertBinaryTree2的行为方式相同,即使我正在将根复制到占位符变量中

public class leetCode_InvertBinaryTree {

public static void main(String[] args) {
    /*
     * initializing some binaryNodes for the tree
     */
    binaryNode a = new binaryNode(4);
    binaryNode b = new binaryNode(2);
    binaryNode c = new binaryNode(7);
    binaryNode d = new binaryNode(1);
    binaryNode e = new binaryNode(3);
    binaryNode f = new binaryNode(6);
    binaryNode g = new binaryNode(9);
    binaryNode inverse;
    
    /*
     * just building the tree
     */
    a.left = b;
    a.right = c;
    b.left = d;
    b.right = e;
    c.left = f;
    c.right = g;
    
    /*
     * Here is the issue!
     */
    System.out.println("Before inverting, root's left branch contains: " + a.left.data);
    inverse = invertBinaryTree(a);
    System.out.println("After inverting, root's left branch contains: " + a.left.data);
    System.out.println("After inverting, inverse's left branch contains: " + inverse.left.data);
}

public static binaryNode invertBinaryTree(binaryNode root){
    if(root.right == null && root.left == null){
        return root;
    }
    else if(root.right == null){
        root.right = root.left;
        root.left = null;
    }
    else if (root.left == null){
        root.left = root.right;
        root.right = null;
    }
    else {
        binaryNode temp = root.left;
        root.left = root.right;
        root.right = temp;
    }
    root.left = invertBinaryTree(root.left);
    root.right = invertBinaryTree(root.right);
    return root;
}

public static binaryNode invertBinaryTree2(binaryNode root){
    binaryNode placeholder = root;
    if(placeholder.right == null && placeholder.left == null){
        return placeholder;
    }
    else if(placeholder.right == null){
        placeholder.right = placeholder.left;
        placeholder.left = null;
    }
    else if (placeholder.left == null){
        placeholder.left = placeholder.right;
        placeholder.right = null;
    }
    else {
        binaryNode temp = placeholder.left;
        placeholder.left = placeholder.right;
        placeholder.right = temp;
    }
    placeholder.left = invertBinaryTree(placeholder.left);
    placeholder.right = invertBinaryTree(placeholder.right);
    return root;
}
这并不重要,但这里有一个binaryNode类,以防它帮助您。我还包括了上面发布的主函数的输出

在反转之前,根的左分支包含:2

反转后,根的左分支包含:7

反转后,反转的左分支包含:7


我建议您添加更多的调试语句,例如在println中,以显示代码每个阶段的结构状态。它将帮助您说明代码正在做什么

出现问题的原因是:

在这种方法中:

public static binaryNode invertBinaryTree(binaryNode root){
…您正在传入节点,一个指向binaryNode类对象的引用的指针**顺便说一句,大多数样式约定要求您调用更像BinaryNode的东西,大小写是标准化的

在binaryNode类的此行中:

public binaryNode left;
…将节点声明为可由任何人修改的成员。此成员的类型为binaryNode,这意味着它引用binaryNode类型的对象的地址

在此代码中:

else if (root.left == null){
    root.left = root.right;
…您正在将名为left的字段(二进制节点的地址)设置为right返回的内容(另一个二进制节点的地址)


……等等。您正在设置引用的值,因此正在更改数据结构的结构。

您应该查找。长话短说:在方法invertBinaryTree中。。。您正在修改传递到方法中的原始树。@Turing85感谢您的及时回复!这怎么可能呢?当我将root传递给该方法时,该方法不是简单地“复制”root而不是对真实的root进行操作吗?请阅读链接。这里已经解释清楚了。也与这个话题有关。如果根被克隆,方法调用会非常慢想象一棵树有数千个节点,因为树是一个递归的数据结构,你必须克隆树中的每个节点…引用与指针不同,Java中也没有指针。引用实际上是指针,只是减少了避免错误的功能。你不能对它们做指针算术,你不能把它们转换成你想要的任何东西,等等@Turing85@lamsomeone所以你看。。。即使用户是管理员,他/她也不能做任何事情。。。。你基本上是这么说的:有区别。仅仅因为引用是通过指针实现的,并不意味着它们是指针。@Turing85:你想对MATLAB中的指针/引用发表意见吗?@MonkeyWidget我们说的是Java。MATLAB与此有什么关系?
else if (root.left == null){
    root.left = root.right;