user16486258
user16486258

Reputation:

Error in Recursive Function Used For Inserting a Node in a Binary Tree in JavaScript

I am getting undefined after the node is inserted in the tree, don't know why is that happening. Here's what is happening - after the node is inserted, the function should return true, but it instead returns undefined. After inserting the node, the code doesn't stop and goes back to if check condition, sets 'current' to '7', this keeps happening until 'current' is '10'(root value) and then it finally goes back to insert() function which returns undefined. My only problem is that why is it returning undefined, and why is it going back to root after inserting the node in the desired place. Can someone please tell me? Am I missing something very small?

by the way, the value I inserted is 8. tree.insert(8);

class Node{
    constructor(val){
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

class BinarySearchTree{
    constructor(){
        this.root = null;
    }

    insert(val){
        if(!this.root){
          this.root = newNode;
          return this;
        }
        let newNode = new Node(val);
        if(val === this.root.val)return false;
     
        function recursiveInsert(current,newNode){ 
            if(newNode.val === current.val)return false;      

            if(newNode.val > current.val){
              if(!current.right){
                  current.right = newNode;             
                  return true;
              }           
              recursiveInsert(current.right,newNode);
            }

            if(newNode.val<current.val){   
              if(!current.left){
                  current.left = newNode;              
                  return true;
            }
            recursiveInsert(current.left, newNode);
          }        
       }    
      return recursiveInsert(this.root,newNode);                         
    }
  }

let tree = new BinarySearchTree();

tree.root = new Node(10);
tree.root.left = new Node(7);
tree.root.right = new Node(15);
tree.root.left.right = new Node(9);

Upvotes: 0

Views: 286

Answers (2)

trincot
trincot

Reputation: 351348

There are these issues:

  • In the if(!this.root){ block, you reference newNode before it has received a value, so move the initialisation of newNode before this if statement.

  • In the same block you return this, but you write that you want to return a boolean, so change that to return true;

  • The recursive calls should be used to return whatever that call returned, so prefix them with return, just like you have done in the last line where you made that initial call.

Demo

I would also suggest building the initial tree with the insert method. And add an iterator so you can have a quick output of your tree in inorder sequence.

Note that there is an else if condition that is always true, so just use else:

class Node {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
    // Add this method for inorder traversal of the values
    * inorder() {
        if (this.left) yield * this.left.inorder();
        yield this.val;
        if (this.right) yield * this.right.inorder();
    }
}

class BinarySearchTree {
    constructor() {
        this.root = null;
    }

    insert(val) {
        let newNode = new Node(val); // First create the node
        if (!this.root) {
            this.root = newNode;
            return true; // you wanted a boolean
        }
        // This is not necessary: it already happens in the function below
        //         if(val === this.root.val)return false;
     
        function recursiveInsert(current,newNode) { 
            if (newNode.val === current.val) return false;      

            if (newNode.val > current.val) {
                if (!current.right) {
                    current.right = newNode;             
                    return true;
                }
                // Return the result
                return recursiveInsert(current.right, newNode);
            } else { // it is the only possibility left
                if (!current.left) {
                    current.left = newNode;              
                    return true;
                }
                // Return the result
                return recursiveInsert(current.left, newNode);
            }        
        }
        
        return recursiveInsert(this.root, newNode);                         
    }
}

let tree = new BinarySearchTree();

// Build the tree only with the insert-method
tree.insert(10);
tree.insert(7);
tree.insert(15);
tree.insert(9);

tree.insert(8); // Add the value you wanted to test with
tree.insert(15); // Try some duplicate

console.log(...tree.root.inorder());

You can make the code still a bit nicer by making the recursive insert function a method of the Node class. Also, enrich the BinarySearchTree constructor, so that it can get a number of values to start with, much like the native Array constructor works.

class Node {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
    
    * inorder() {
        if (this.left) yield * this.left.inorder();
        yield this.val;
        if (this.right) yield * this.right.inorder();
    }
    
    insert(val) { 
        if (val === this.val) return false;      

        if (val > this.val) {
            if (this.right) return this.right.insert(val);
            this.right = new Node(val); 
        } else {
            if (this.left) return this.left.insert(val);
            this.left = new Node(val);             
        }        
        return true;
    }
}

class BinarySearchTree {
    constructor(...values) {
        this.root = null;
        for (let val of values) this.insert(val);
    }

    * inorder() {
        if (this.root) yield * this.root.inorder();
    }

    insert(val) {
        if (this.root) return this.root.insert(val);
        this.root = new Node(val);
        return true;
    }
    
    
}

let tree = new BinarySearchTree(10, 7, 15, 9);
tree.insert(8);
tree.insert(15);

console.log(...tree.inorder());

Upvotes: 1

Dani
Dani

Reputation: 895

You should return the recursiveCall or you will get undefined because the recursive call take time to execute and the function won't wait for it to return something.

// ...code
return recursiveInsert(current.right,newNode);
// and
return recursiveInsert(current.left,newNode);

Upvotes: 0

Related Questions