js数据结构之二叉树

二叉树实现如下

    function Node(data, left, right){
        // 保存当前节点key值
        this.data = data
        // 指向左子节点
        this.left = left
        // 指向右子节点
        this.right = right
    }
    function BST() {
        this.root = null
        this.show = () => {
            return this.root;
        };
        // 插入节点
        this.insert = function(data){
            let node = new Node(data,null,null)
            if(this.root == null){ // 这时没有根节点
                this.root = node
            } else {
                let current = this.root
                let parent;
                while(true){
                    parent = current
                    //当插入的值小于根节点的值时,将值作为左节点插入
                    if(data < current.data){
                        current = current.left;
                        if (current === null) {
                            parent.left = node;
                            break;
                        }
                    } else {
                        current = current.right;
                        if(current === null) {
                            parent.right = node;
                            break;
                        }
                    }
                }
            }
        }
       // 先序遍历
        this.preOrder = function(node){
            let result = []
            let pre = function(node) {
                if (node) {
                    result.push(node.data)
                    pre(node.left)
                    pre(node.right)
                }
                
            }
            pre(node)
            return result
        }
       // 中序遍历
       this.inOrder = function(node){
            let result = []
            let inTraverse = function(node) {
                if (node) {
                    inTraverse(node.left)
                    result.push(node.data)
                    inTraverse(node.right)
                }
                
            }
            inTraverse(node)
            return result
        }
         // 后序遍历
       this.afterOrder  = function(node){
            let result = []
            let afterTraverse = function(node) {
                if (node) {
                    afterTraverse(node.left)
                    afterTraverse(node.right)
                    result.push(node.data)
                }
                
            }
            afterTraverse(node)
            return result
        }
       // 获得最小值的节点
       this.getMin = function() {
            let current = this.root
            while(current.left) {
                current = current.left
            }
            return current.data
       }
       // 获得最大值的节点
       this.getMax = function() {
            let current = this.root
            while(current.right) {
                current = current.right
            }
            return current.data
       }
        // 寻找给定数据的节点
        this.find = function(data){
            let current = this.root
            while(current){
                if(current.data == data) {
                    return current
                } else if(data < current.data) {
                    current = current.left
                } else {
                    current = current.right
                }
            }
            return null;
        }
        // 删除节点
        this.remove = function(data) {
            this.root = this._removeNode(this.root,data)
        }
        // 删除节点时,一共可以分为三种情况
        // 1.待删除的节点是叶子节点。
        // 2.待删除的节点没有左子节点,或者没有右子节点。
        // 3.待删除的节点的左右子节点均存在。
        this._getSmallest = function(node){
            while(node.left){
                node = node.left
            }
            return node
        }
        this._removeNode = function(node,data) {
            if(node == null) {
                return null
            }
            if(data == node.data){
                // 叶子节点
                if(node.left == null && node.right ==null) {
                    return null
                }
                // 没有左节点的节点
                if (node.left == null) {
                    return node.right
                }
                // 没有右节点的节点
                if (node.right == null) {
                    return node.left
                }
                 // 有两个节点的节点
                /*
                    做法:
                        找到待删节点的右子树上的最小值创建一个临时节点
                        将临时节点上的值复制到待删节点,然后再删除临时节点
                */
                // 寻找右节点的最小值
                let tmpNode = this._getSmallest(node.right)
                node.data = tmpNode.data
                node.right = this._removeNode(node.right,tmpNode.data)
                return node
            } else if(data < node.data) { // 待删节点在左子树上
                node.left = this._removeNode(node.left,data)
                return node
            } else {   // 待删除节点在右子树上
                node.right = this._removeNode(node.right, data);
                return node;
            }
        }
    }

 

测试

插入节点 及 遍历

let bst = new BST()
bst.insert(20)
bst.insert(8)
bst.insert(7)
bst.insert(22)
bst.insert(15)
bst.insert(21)
bst.insert(32)
bst.insert(11)
bst.insert(16)
bst.insert(48)
  console.log(bst.preOrder(bst.root)) // 先序遍历: [20, 11, 7, 15, 16, 22, 21, 32, 48]
  console.log(bst.inOrder(bst.root)) // 中序遍历: [7, 11, 15, 16, 20, 21, 22, 32, 48]
  console.log(bst.afterOrder(bst.root)) // 后序遍历: [7, 16, 15, 11, 21, 48, 32, 22, 20]

新建后的二叉排序树如下图所示

 

删除节点8

bst.remove(8)

 

删除后的二叉排序树如下图所示

posted @ 2020-06-11 16:13  谬论结局  阅读(259)  评论(0编辑  收藏  举报