在bst实现中传递的Java参数

时间:2016-03-26 21:37:59

标签: java parameter-passing binary-search-tree

我在使用C很长一段时间后回到Java并且已经陷入了一个简单的概念。我开始编写一个基本的BST实现来恢复我的方向,并且认为我理解了Java的值传递值参数传递(是的,我知道甚至对象引用都是通过值传递的,这是一种非常常见的误解)。

我递归地实现了添加功能,如下面的代码所示,但是我发现如果我实际上没有返回节点值,它就不起作用。我已经注释掉了不起作用的线条,并用可用于比较的线条替换它们。

我的想法是,因为实际根节点的引用副本正被传递给add函数,所以每个函数调用中完成的更改都是在内存中的实际对象上完成的,所以如果我添加一个节点到左或右分支,应保留。

我感到非常尴尬,因为我知道我必须在这里遗漏一些非常简单的东西,但阅读java参数传递似乎让我想知道为什么我错了。谢谢您的帮助。

public class BinaryTree {

    TreeNode root;

    public BinaryTree(){
        root = null;
    }

    void add(int item){
        root = add(root,item);
        //add(root,item);
    }

    //public void TreeNode add(TreeNode node, int item){
    public TreeNode add(TreeNode node, int item){
        if(node == null){
            node = new TreeNode(item);
        } else if(item <= node.getItem()){
            node.setLeft(add(node.getLeft(),item));
            //add(node.getLeft(),item);
        } else if(item > node.getItem()){
            node.setRight(add(node.getRight(),item));
            //add(node.getRight(),item);
        } 
        return node;
        //return;
    }
    static void printTree(BinaryTree tree){
        printTree(tree.root);
    }
    static void printTree(TreeNode node){
        if(node == null){
            System.out.println("Tree Empty");
            return;
        }
        if(node.getLeft() != null)
            printTree(node.getLeft());
        if(node.getRight() != null){
            System.out.print(node.getItem()+ ", ");
            printTree(node.getRight());
        } else {
            System.out.print(node.getItem()+ ", ");
        }
        return;

    }

    public static void main(String args[]){
        BinaryTree tree1 = new BinaryTree();
        tree1.add(10);
        tree1.add(3);
        tree1.add(5);
        printTree(tree1);
    }
}`

1 个答案:

答案 0 :(得分:1)

这是因为在你的void add方法中,你将root设置为等于TreeNode add的结果,所以你必须返回一些东西,否则root将为null。例如,让我们将第一个元素添加到BST。运行TreeNode add方法后,必须返回一些内容,因为最终会在root方法中将其分配给void add。这里有一个概述,如果你不返回任何东西会发生什么。

void add(10) gets executed
root = add(root, 10)
TreeNode add(root, 10) gets executed
if(node == null) evaluates to true
node = new TreeNode(10); // this is where java being pass by value matters

您认为root实际上正在更改为新的TreeNode对象,其项值为10.但是,这不会发生。而是每当调用接受参数的方法时,指针就会指向这些参数中的对象。因此,调用TreeNode add(root, 10)会创建指向root的指针。此指针名为node,因此当您在此处的最后一行中更改node时,它会更改指针node指向的内容,而root保持不变。如果你没有返回node,那么你对这个刚刚创建的新TreeNode对象的引用一无所知,所以它最终会在Java的垃圾收集中丢失。