user3218743
user3218743

Reputation: 589

BST simple insertion with recursion

I am trying to write a small function to insert a node to a BST. The "insert" function is working correctly. I changed it to "insert2", where it doesn't work. I cannot figure out why it doesn't work. What is the difference between "insert" and "insert2" in runtime?

Insert method

public void insert(Node node, int x) {
    if (x < node.val) {
        if (node.left == null) node.left = new Node(x);
        else insert(node.left, x);
    } else {
        if (node.right == null) node.right = new Node(x);
        else insert(node.right, x);
    }
}

insert2 method

public void insert2(Node node, int x) {
        if (node == null) {
            node = new Node(x);
            return;
        }
        if (x < node.val) insert2(node.left, x);
        else insert2(node.right, x);
    }

Definition of Node

public class Node {
    int val;
    Node left, right;
    public Node (int _val) {
        this.val = _val;
    }
}

Thanks in advance.

Upvotes: 1

Views: 77

Answers (1)

Sylwester
Sylwester

Reputation: 48775

Java is a pass by value language. This means that when you pass a variable to a method, either primitive or objects, the method cannot change that variable since it doesn't know anything about that variable. The method has it's own variable and assigning anything new to a argument variable only persist in that scope and does not mutate other bindings or objects.

When you do have:

public static void update(String str) {
  str = "changed";
}

And do:

String s = "hello";
update(s);
System.out.println(s);

It will print "hello" since although the address of "hello" was passed to update, update only update the local variable to the address of a new string. Assignment never changed the variable that was used to apply the method or the objects both variables points to.

String h = "hello";
String w = "world";
String x = h; // x points to the same string as h
x = w;        // x got it's value changed to point to w
System.out.println(h + " " + w);

The last statement prints "hello world", not "world world" as if assignment mutated the previous object.

So what happened in your insert methods?

insert2 overwrites a local variable that happens to be null to a new Node, but it has nothing to do with the original argument passed. The newly created node is only accessible from that scope so when it returns the new node is ready to be garbage collected. The tree passed to the original method was never mutated thus it never gets a new value.

If you look at insert it takes a not null Node and alters right or left property on either that node or one of it's descendants. Thus when you inspect the original argument the tree has changed since it didn't mutate arguments, but the object itself.

Mutating objects is not the same as mutating variables.

Upvotes: 1

Related Questions