请帮助我理解为什么我的引用(祖先)在这里为空

Please help me understand why is my reference (ancestor) null here

System.out.println(ancestor.data)LCA() 方法中抛出 NPE,即使我的递归 findlca()ancestor 值设置为值为 4 的节点。我可以通过使用看到这一点调试指针。一旦我走出我的递归 ancestor 字段设置为空。对象引用不应该改变,对吧?

public class LCA {
    
    static class Node {
        int data;
        Node left;
        Node right;
        Node(int data){
            this.data =data;
        }
    }
    
    public static Node lca(Node root, int v1, int v2) {
        Node ancestor = null;
        findlca(root, v1, v2, ancestor);
        System.out.println(ancestor.data);
        return ancestor;
    }
    
    public static boolean findlca(Node node, int v1, int v2, Node ancestor){
        if(node==null){
            return false;
        }
        boolean nodeMatch = false;
        if(node.data==v1 || node.data==v2){
            nodeMatch = true;
        }
        boolean leftMatch = findlca(node.left, v1, v2, ancestor);
        boolean rightMatch = findlca(node.right, v1, v2, ancestor);
        if((leftMatch && rightMatch) || (leftMatch && nodeMatch) || (rightMatch && nodeMatch)){
            ancestor = node;
        }
        return leftMatch || nodeMatch || rightMatch;
    }
    
    public static void main(String[] args) {
        Node root = new Node(4);
        root.left = new Node(2);
        root.right = new Node(7);
        
        root.left.left = new Node(1);
        root.left.right = new Node(3);
        
        root.right.left = new Node(6);
        Node ancestor = lca(root, 1, 7);
        System.out.println(ancestor.data);
    }
}

我认为article这样会回答你的问题。

Whenever an object is passed as an argument, an exact copy of the reference variable is created which points to the same location of the object in heap memory as the original reference variable.
As a result of this, whenever we make any change in the same object in the method, that change is reflected in the original object. However, if we allocate a new object to the passed reference variable, then it won't be reflected in the original object.

要修复您的代码,您可以在 class 节点中添加空构造函数,使用空构造函数创建对象并在 findlca(...)

中填充他的字段

Java is pass-by-value, not pass-by-reference,因此 findlca() 中的 ancestor 变量是 而不是 您在 [= 开头声明的 ancestor 14=],而是它的一个副本。当然,它们可能引用同一个对象,但它们本身是不同的变量。

要修复它,只需将 lca() 中的 ancestor 分配给 findlca() 的输出即可。

ancestor = findlca(root, v1, v2, ancestor)