I'm building a Binary Search tree and I made a function to insert new values recursively, I tried to put its parameters by two ways:
1- by reassign the parameter by assignment operator with the new value
2- by puting the new value of parameter without reassigning it with assignment operator
for me I don't see nor know what's the difference between them, I think every time the function call itself it reassign the node parameter to its right or left in both of them. my question is why don't both ways work the same, and what's the difference btween these two ways?
here's the code for both and the output I got:
class Node {
constructor(key, left, right) {
this.key = key || null;
this.left = left || null;
this.right = right || null;
}
}
class Tree {
constructor(arr) {
this.tree = this.buildTree(arr);
}
......
}
let tree = new Tree([3, 2, 4, 1, 6, 7, 5, 8, 10, 9, 12, 11])
tree.insert(100)
#1- by reassign the parameter by assignment operator with the new value
insert(value, node = this.tree) {
if (node == null) return node = new Node(value)
if (value == node.key) return node; // prevent dublicated values;
if (value > node.key) node.right = this.insert(value, node = node.right);
else if (value < node.key) node.left = this.insert(value, node = node.left);
return node
}
===> this way didn't put the new node in the right place and it deleted other nodes from the tree this is its output :
#2- by puting the new value of parameter with reassigning it without assignment operator
insert(value, node = this.tree) {
if (node == null) return node = new Node(value)
if (value == node.key) return node; // prevent dublicated values;
if (value > node.key) node.right = this.insert(value, node.right);
else if (value < node.key) node.left = this.insert(value, node.left);
return node
}
===> this way works well and insert the new value in the right place without removing any parent nodes this is its out put
Perhaps this will help. The following probably doesn't look correct:
insert(value, node = this.tree) {
if (node == null) return node = new Node(value)
if (value == node.key) return node; // prevent dublicated values;
if (value > node.key) {
node = node.right;
node.right = this.insert(value, node);
} else if (value < node.key) {
node = node.left;
node.left = this.insert(value, node);
}
return node;
}
And of course it's not. We don't want to change the identity of node
before we return it. But that is, in essence, what your code does.
This line does the same as the if
block above:
if (value > node.key) node.right = this.insert(value, node = node.right);
First, we reassign the value of our node
variable to node.right
. Then we call the insert
with the new node value. Then at the end of the function, we return node
, with its new value.
There is a strong argument for never, ever reassigning an input parameter. This is simply one piece of evidence for that idea.