SOURCE

function BinarySearchTree() {
    this.root = null;

    function Node(key) {
        this.key = key;
        this.right = null;
        this.left = null;
    }

    // 插入节点
    BinarySearchTree.prototype.insert = function(key) {
        // 根据key创建节点
        const newNode = new Node(key);

        // 判断根节点是否有值
        if(!this.root) {
            this.root = newNode;
        } else {
            this.insertNode(this.root,newNode)
        }

    }


    // 内置函数,递归与新节点比较
    BinarySearchTree.prototype.insertNode = function(node,newNode) {
        if(newNode.key < node.key) {
            // 左插入
            if(node.left == null) {
                node.left = newNode
            } else {
                this.insertNode(node.left,newNode)
            }
        }

        if(newNode.key > node.key) {
            // 右插入
            if(node.right == null) {
                node.right = newNode;
            } else {
                this.insertNode(node.right,newNode)
            }
        }
    }

    // 先序遍历
    BinarySearchTree.prototype.preOrderTraverse = function(handler) {
        this.preOrderTraverseNode(this.root,handler)
    }

    BinarySearchTree.prototype.preOrderTraverseNode = function(node,handler) {
        if(node !== null) {
            // 处理节点
            handler(node.key)
            // 处理节点的左子节点
            this.preOrderTraverseNode(node.left,handler)
            // 处理节点的右子节点
            this.preOrderTraverseNode(node.right,handler)
        }  
     }


     // 中序遍历
     BinarySearchTree.prototype.midOrderTraverse = function(handler) {
         this.midOrderTraverseNode(this.root,handler)
     }

     BinarySearchTree.prototype.midOrderTraverseNode = function(node,handler) {
         if(node !==null)  {
             // 处理左子节点
             this.midOrderTraverseNode(node.left,handler);
             // 处理节点
             handler(node.key);
             // 处理右子节点
             this.midOrderTraverseNode(node.right,handler);
         }
     }


     // 后序遍历
    BinarySearchTree.prototype.postOrderTraverse = function(handler) {
         this.postOrderTraverseNode(this.root,handler)
     }

     BinarySearchTree.prototype.postOrderTraverseNode = function(node,handler) {
         if(node !==null)  {
             // 处理左子节点
             this.postOrderTraverseNode(node.left,handler);
             // 处理右子节点
             this.postOrderTraverseNode(node.right,handler);
            // 处理节点
             handler(node.key);
         }
     }


    // 最值
     BinarySearchTree.prototype.min = function() {
         let node = this.root;
         while(node.left !== null) {
             node = node.left;
         }
         return node.key;
     }

     BinarySearchTree.prototype.max = function() {
         let node = this.root;
         while(node.right !== null) {
             node = node.right
         }
         return node.key
     }


     BinarySearchTree.prototype.remove = function(key) {
         // 从root出发寻找删除节点
         let current = this.root;
         let parent = null;
         // 是否为左子节点
         let isLeft = false;

         while(current.key != key) {
             parent = current;
             if(key < current.key) {
                current = current.left;
                isLeft = true;
             } else {
                 current = current.right;
                 isLeft = false
             }
            
            // 找到末尾依旧没有找到
             if(current == null) return false;
         }   

         // 找到的节点是叶子节点
         // 情况1是叶子节点也是根节点
         if(current.right == null && current.left == null) {
             if(current == this.root) {
                 this.root = null;
             } else if(isLeft) {
                 parentleft = null;
             } else {
                 parent.right = null;
             }
         } 
         // 情况2当前节点只存在一个子节点
         else if(current.right == null) {
             // 情况2当前节点只存在一个子节点
             // 当前节点只存在左子节点
             // 当前节点是根节点
             if(current == this.root) {
                 this.root = current.left
             } else if(isLeft) {
                 // 当前节点是左子节点
                 parent.left = current.left
             } else {
                 // 当前节点是右子节点
                 parent.right = current.left
             }
         } else if(current.left == null) {
             // 当前节点只存在右子节点
             // 当前节点是根节点
               if(current == this.root) {
                 this.root = current.right
                } else if(isLeft) {
                    // 当前节点是左子节点
                    parent.left = current.right
                } else {
                    parent.right =current.right
                }
         } else {
             // 找到后续节点
            let successor = this.getSuccessor(current);
            // 判断是否为根节点,左子节点,右子节点
             if(current == this.root) {
                 this.root = successor
                } else if(isLeft) {
                    // 当前节点是左子节点
                    parent.left = successor
                } else {
                    parent.right = successor
            }
         }

     }

     // 获取后续节点,即从要删除的节点的右边开始查找最小的值
     BinarySearchTree.prototype.getSuccessor = function(delNode) {
        // 定义变量,保存要找到的后续
         let current = delNode.right;
         let successorParent = delNode; // 后续节点的父节点 
         let successor = delNode.right; // 后续节点
        
        // 不断获取右边子树的深层左节点
        while(current.left != null) {
            successorParent = successor;
            current = current.left;
            successor = current;
            console.log(successor)
        }

        // 判断寻找到的后续节点是否直接就是要删除节点的 right
         if (successor != delNode.right) {
            successorParent.left = successor.right;
            successor.right = delNode.right;
        }
        

        return successor;
     }  

}


const BST = new BinarySearchTree();

BST.insert(11);
BST.insert(7);
BST.insert(15);
BST.insert(5);
BST.insert(3);
BST.insert(9);
BST.insert(8);
BST.insert(10);
BST.insert(13);
BST.insert(12);
BST.insert(14);
BST.insert(20);
BST.insert(18);
BST.insert(25);
BST.insert(6);


BST.remove(9)




console 命令行工具 X clear

                    
>
console