BinarySearchTree

//##树
    //1.二叉树:几乎所有的树都可以表示成二叉树的形式
    //2.完全二叉树:只有叶节点不是满的,且优先为左侧节点
    //3.二叉搜索树(BST):
    //非空左子树的所有键值小于根节点的键值
    //非空右子树的所有键值大于根节点的键值
    //左右子树本身也是二叉搜索树
    //利用了二分查找的思想,查找所需的最大次数为BST的深度
        function BinarySearchTree() {
            function Node(key) {
                this.key = key;
                this.left = null;
                this.right = null;
            }
            this.root = null;

            BinarySearchTree.prototype.insert = function(key) {
                var newNode = new Node(key);
                if(this.root == null) {
                    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);
                    }
                }else{
                    if(node.right == null) {
                        node.right = newNode;
                    }else{
                        this.insertNode(node.right, newNode);
                    }
                }
            }

            //先序遍历:先访问根节点,然后左右子树
            BinarySearchTree.prototype.preOrderTraversal = function(handler) {
                this.preOrderTraversalNode(this.root, handler);
            }
            BinarySearchTree.prototype.preOrderTraversalNode = function(node, handler) {
                if(node != null) {
                    handler(node.key);
                    this.preOrderTraversalNode(node.left, handler);
                    this.preOrderTraversalNode(node.right, handler);
                }
            }

            //使用
            var bst = new BinarySearchTree();
            var resultString = "";
            bst.preOrderTraversal(function(key){
                resultString += key + "";
            })
            alert(resultString);

            //中序遍历:根节点第二次访问
            BinarySearchTree.prototype.inOrderTraversal = function(handler) {
                this.inOrderTraversalNode(this.root, handler);
            }
            BinarySearchTree.prototype.inOrderTraversalNode = function(node, handler) {
                if(node != null) {
                    this.inOrderTraversalNode(node.left, handler);
                    handler(node.key);
                    this.inOrderTraversalNode(node.right, handler);
                }
            }

            //后序遍历:先访问左右子树,最后访问根节点
            BinarySearchTree.prototype.postOrderTraversal = function(handler) {
                this.postOrderTraversalNode(this.root, handler);
            }
            BinarySearchTree.prototype.postOrderTraversalNode = function(node, handler) {
                if(node != null) {
                    this.postOrderTraversalNode(node.left, handler);
                    this.postOrderTraversalNode(node.right, handler);
                    handler(node.key);
                }
            }

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

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

            BinarySearchTree.prototype.search = function(key) {
                return this.searchNode(this.root, key);
            }
            BinarySearchTree.prototype.searchNode = function(node,key) {
                if(node == null) {
                    return false;
                }
                if(node.key > key) {
                    return this.searchNode(node.left, key);
                }else if(node.key < key) {
                    return this.searchNode(node.right, key);
                }else{
                    return true;
                }
            }

            //删除节点:
            //1.找到节点
            //2.删除节点
            //叶节点:父节点的left/right为null
            //一个子节点:父节点指向子节点
            //两个子节点:右子树的最小节点去更新这个节点,将原点删除,最后返回新的引用(前驱/后继)
            BinarySearchTree.prototype.remove = function(key) {
                var current = this.root;
                var parent = null;
                var isLeftChild = true;
                while(current.key != key) {
                    parent = current;
                    if(key < current.key) {
                        isLeftChild = true;
                        current = current.left;
                    }else{
                        isLeftChild = false;
                        current = current.right;
                    }
                    if(current == null) {
                        return false;
                    }
                }

                // 3.删除的结点是叶结点
                if (current.left === null && current.right === null) {
                    if (current == this.root) {
                        this.root == null
                    } else if (isLeftChild) {
                        parent.left = null
                    } else {
                        parent.right = null
                    }
                }

                // 4.删除有一个子节点的节点
                else if (current.right === null) {
                    if (current == this.root) {
                        this.root = current.left
                    } else if (isLeftChild) {
                        parent.left = current.left
                    } else {
                        parent.right = current.left
                    }
                } else if (current.left === null) {
                    if (current == this.root) {
                        this.root = current.right
                    } else if (isLeftChild) {
                        parent.left = current.right
                    } else {
                        parent.right = current.right
                    }
                }

                // 5.删除有两个节点的节点
                else {
                    // 1.获取后继节点
                    var successor = this.getSuccessor(current)

                    // 2.判断是否是根节点
                    if (current == this.root) {
                        this.root = successor
                    } else if (isLeftChild) {
                        parent.left = successor
                    } else {
                        parent.right = successor
                    }

                    // 3.将删除节点的左子树赋值给successor
                    successor.left = current.left
                }

                return true
            }

            // 找后继的方法
            BinarySerachTree.prototype.getSuccessor = function (delNode) {
                // 1.使用变量保存临时的节点
                var successorParent = delNode
                var successor = delNode
                var current = delNode.right // 要从右子树开始找

                // 2.寻找节点
                while (current != null) {
                    successorParent = successor
                    successor = current
                    current = current.left
                }

                // 3.如果是删除图中15的情况, 还需要如下代码
                if (successor != delNode.right) {
                    successorParent.left = successorParent.right
                    successor.right = delNode.right
                }
                return successor;
            }
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值