有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java调用以getter作为参数的函数不会保留引用?

我的代码有问题,我正在创建一个二叉搜索树数据结构,当我用一个节点的子节点调用一个函数,然后在函数中给该子节点赋值时,它不会更新节点的子节点

//*** Pseudo-ish Code ***

class BSTNode {

    private BSTNode lChild;
    private BSTNode rChild;
    private int key;

    public BSTNode(int key) {
        this.lChild = null;
        this.rChild = null;
        this.key = key;
    }

    //getters and setters for each field ^
}

class BST {

    private BSTNode root;

    public BST() {
        this.root = null;
    }

    public void insert(BSTNode currentNode, int value) {

        BSTNode newNode = new BSTNode(value);

        if (currentNode == null) {

            currentNode = newNode;
            if (this.root == null) {
                this.root = currentNode;
            }

        } else {

            //ignore the newNode == currentNode value statement right now

            if (newNode.getValue() < currentNode.getValue()) {
                insert(currentNode.getlChild(), value);
            } else if (newNode.getValue() > curNode.getValue()) {
                insert(curNode.getrChild(), value);
            }
        }
    }

    //getters and setters
}

我仍然想自己找出代码,但我很好奇,如果我要用以下代码运行代码:

BST testBST = new BST();

testBST.insert(testBST.getRoot(), 10);
testBST.insert(testBST.getRoot(), 7);

System.out.print(testBST.getRoot()); 
System.out.print(" ");
System.out.print(testBST.getRoot().getlChild());

这将输出10,然后输出一个NullPointerException。我明白这是因为不知何故,7没有被分配为10的lChild,但我不知道为什么?这是我遇到的范围问题,还是因为我在insert函数中使用getlChild()递归调用,所以无法访问实际的私有lChild字段

注意:我正在使用sysout调试代码,我注意到递归确实有效,它确实将7正确地分配给currentNode,但一旦函数完成运行,currentNode就好像不再引用初始根节点的lChild


共 (1) 个答案

  1. # 1 楼答案

    问题在于:

    BSTNode newNode = new BSTNode(value);
    

    每次计算机调用递归方法insert(),它都会创建一个new BSTNode()。每次只想添加一个new BSTNode(),但它会一次又一次地创建节点。例如,您想要添加3,为此它必须调用insert()4次。而不是只创建1节点,而是创建4节点

    我所做的,除了消除一些错误之外,我还在BSTNode class中创建了递归insertValue()方法。所以你不必每次调用这个方法时都跟踪currentNode。每个节点都将调用自己的insertValue()方法

    //*** Pseudo-ish Code ***
    class BSTNode 
    {
        public BSTNode lChild;
        public BSTNode rChild;
        public int key;
    
        public BSTNode(int key) 
        {
            this.lChild = null;
            this.rChild = null;
            this.key = key;
        }
    
        /* Create INSERT function in BSTNode class so that you dont have to give the "CurrentNode" everytime
           you call this method, Now you just have to pass the "Key"*/
        public void insertValue(int insertValue)
        {
            if(insertValue < key)
            {
                if(lChild == null)
                    lChild = new BSTNode(insertValue);
                else
                    lChild.insertValue(insertValue);
            }
            else if(insertValue > key)
            {
                if(rChild == null)
                    rChild = new BSTNode(insertValue);
                else
                    rChild.insertValue(insertValue);
            }
            else;
        }
    }
    
    class BST 
    {
        private BSTNode root;
        public BST() 
        {
            this.root = null;
        }
    
        // just create the root if not present else it'll call the recursive method of BSTNode class
        public void insert(int value)
        {
            if(root == null)
                root = new BSTNode(value);
            else
                root.insertValue(value);
        }
    
        // you didn't provide these methods so i wrote my own just to get your code runing 
        public BSTNode getRoot()
        {
            return root;
        }
    
        public int getRootValue()
        {
            return root.key;
        }
    }
    
    public class BSTMain
    {
        public static void main(String[] args)
        {   
            BST testBST = new BST();
            testBST.insert(10);
            testBST.insert(7);
    
            System.out.print(testBST.getRootValue()); 
            System.out.print(" ");
            System.out.print(testBST.getRoot().lChild.key);
        }
    }
    

    注意:我添加了一些方法,比如getRoot(),只是为了让代码正常工作,因为您没有提供它们