Search code examples
javascriptreferencebinary-search-tree

BST remove method is not working in JavaScript


I am trying to make a Binary Search Tree (BST) class in JavaScript.

In JS objects are passed/assigned by reference but it looks like that this has some issue in the remove method. The remove method is not removing the node which I want it to remove.

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

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

  add(value){
    if(!this.root){
      this.root = new Node(value);
      return this;
    }
    addNode(this.root);
    return this;

    function addNode(node) {
      if(value < node.value){
        if(!node.left){
          node.left = new Node(value);
        }else{
          addNode(node.left);
        }
      }

      if(node.value < value){
        if(!node.right){
          node.right = new Node(value);
        }else{
          addNode(node.right);
        }
      }
    }
  }

  find(value){
    if(!this.root){
      return;
    }
    return findNode(this.root);

    function findNode(node) {
      if(node.value === value){
        return node;
      }
      if(value < node.value){
        if(!node.left){
          return;
        }else{
          return findNode(node.left);
        }
      }else{
        if(!node.right){
          return;
        }else{
          return findNode(node.right);
        }
      }
    }

  }

  remove(value){
    if(!this.root){
      return this;
    }
    return removeNode(this.root);

    function removeNode(node) {
      if(node.value === value){
        return actualRemoval(node);
      }
      if(value < node.value){
        if(!node.left){
          return;
        }else{
          return removeNode(node.left);
        }
      }else{
        if(!node.right){
          return;
        }else{
          return removeNode(node.right);
        }
      }
    }

    function actualRemoval(node) {
      let tmp = Object.assign(node);
      if(!node.left && !node.right){
        node = null;
        return tmp;
      }
      if(!node.left){
        node = node.right;
        return tmp;
      }
      if(!node.right){
        node = node.left;
        return tmp;
      }
      //if the node has both the children.
      node.value = popMin(node.right).value;
      return tmp;
    }

    function popMin(node) {
      if(!node.left){
        let tmp = Object.assign(node);
        node = node.right;
        return tmp;
      }
      return popMin(node.left);
    }
  } //end of function remove()
} //end of class BST

let myBST = new BST();
myBST.add(5).add(6).add(3).add(4).add(7).add(5.5)
// console.log(myBST.add(5).add(6).add(3).add(4).add(7).add(5.5));
// console.log(myBST.find(6));

console.log(myBST.remove(3));
console.log(myBST);

In the second to last line I am trying to remove a node with value 3. But the last line displays a tree with node 3 present in it.


Solution

  • remove(value){
        if(!this.root){
          return this;
        }
        return removeNode(this.root, null);//second argument is the
    
        function removeNode(node, parent, leftOrRight) {
          if(node.value === value){
            return actualRemoval(node, parent, leftOrRight);
          }
          if(value < node.value){
            if(!node.left){
              return;
            }else{
              return removeNode(node.left, node, "l");
            }
          }else{
            if(!node.right){
              return;
            }else{
              return removeNode(node.right, node, "r");
            }
          }
        }
        function actualRemoval(node, parent, leftOrRight) {
          let tmp = Object.assign(node);
          if(!node.left && !node.right){
            if(parent){
              if(leftOrRight === "l"){
                parent.left = null;
              }else{
                parent.right = null;
              }
            }else{
              node = null;
            }
            return tmp;
          }
          if(!node.left){
            if(parent){
              if(leftOrRight === "l"){
                parent.left = node.right;
              }else{
                parent.right = node.right;
              }
            }else{
              node = node.right; //this case runs once node is root
            }
            return tmp;
    
          }
          if(!node.right){
            if(parent){
              if(leftOrRight === "l"){
                parent.left = node.leftt;
              }else{
                parent.right = node.left;
              }
            }else{
              node = node.left; //this case runs once node is root
            }
            return tmp;
          }
          //if the node has both the children.
          node.value = popMin(node.right, node, "r").value;//it is always called for right side with popMin
          return tmp;
        }
        function popMin(node, parent, leftOrRight) {
          if(!node.left){
            let tmp = Object.assign(node);
            if(leftOrRight == "l"){
              parent.left = node.right;
            }else{
              parent.right = node.right;
            }
            return tmp;
          }
          return popMin(node.left, node, "l");
        }
      }