Data structure: Binary Search Tree


			class Node {

  constructor(data, left = null, right = null){
    this.data = data;
    this.left = null;
    this.right = null;
  }
}

class BST {
 
  constructor(){
     this.root = null;
  }
  add(data){
    const node = this.root;
    if(node === null){
      this.root = new Node(data);
      return;
    }
    else {
      const searchInTree = function(node){
        if(data > node.data){
          if(node.right === null){
            node.right = new Node(data);
            return;
          }
          else {
            return searchInTree(node.right);
          }
        }
        else if(data < node.data) {
          if(node.left === null){
            node.left =  new Node(data);
            return;
          }
          else {
            return searchInTree(node.left);
          }
        }
        else {
          return null;
        }
      };

      return searchInTree(node);
    }
  }

  findMin(){
    let current = this.root;
    while(current.left !== null){
      current = current.left;
    }
    return current.data;
  }

  findMax(){
    let current = this.root;
   // console.log("print current ", current);
    while(current.right !== null){
      current = current.right;
    }
    return current.data;
  }

  find(data){

  }

  isPresent(data){

  }

  findMinHeight(node = this.root){
    if(node === null){
      return -1;
    }

    let left = this.findMinHeight(node.left);
    let right = this.findMinHeight(node.right);
    if(left < right){
      return left+1;
    }
    else {
      return right+1;
    }
  }

  findMaxHeight(node = this.root){
    if(node === null){
      return -1;
    }
    let left = this.findMaxHeight(node.left);
    let right = this.findMaxHeight(node.right);
    if(left > right){
      return left+1;
    }
    else {
      return right+1;
    }
  }

  remove(data){
    const removeData = function(node, data){
      if(node === null){
        return null;
      }
      else if(data === node.data){
        if(node.left === node.right === null){
          return null;
        }
        
        if(node.left === null) {
          return node.right;
        }

        if(node.right === null){
          return node.left;
        }

        let tmpNode = node.right;
        while(tmpNode.left !== null){
          tmpNode = tmpNode.left;
        }
        node.data = tmpNode.data;
        node.right = removeData(node.right, tmpNode.data);
        return node;

      }
      else if(data < node.data){
        node.left = removeData(node.left, data);
        return node;
      }
      else {
        node.right = removeData(node.right, data);
        return node;
      }
    }
    removeData(this.root, data);
  }

  isBalanced(){

  }
  inOrder(){
    if(this.root === null){
      return null;
    }
    else {
      const result = new Array();
      const inOrderTraversal = function(node){
        node.left && inOrderTraversal(node.left);
        result.push(node.data);
        node.right && inOrderTraversal(node.right);
      }
      inOrderTraversal(this.root);
      return result;

    }
  }
}


var bst = new BST();
bst.add(4);
bst.add(2);
bst.add(3);
bst.add(8);
bst.add(1);
bst.add(3);
bst.add(8);
bst.add(1);
bst.add(10);
bst.add(11);
bst.add(12);
bst.remove(12);

console.log(bst.findMinHeight());
console.log(bst.inOrder());