JavaScript二叉搜索树

        function BinarySearchTree(){
            var Node = function(key){
                this.key = key;
                this.left = null;
                this.right = null;
            };
            var root = null;   //根元素
            //在树中插入一个新的键
            this.insert = function(key){
                //创建用来表示新节点的Node实例
                var newNode = new Node(key);
                //插入的节点是树的第一个节点,就将根节点指向新节点
                if(root === null){
                    root = newNode;
                }else{
                    //节点加载非根节点的 其他位置
                    insertNode(root,newNode);
                }
            };
            //找到新节点应该插入的正确位置
            var insertNode = function(node, newNode){
                //如果新节点的键小于当前节点的键
                if(newNode.key< node.key) {
                    //检查当前节点的左侧子节点,如果它没有左侧子节点,就在那里插入新的节点
                    if (node.left === null) {
                        node.left = newNode;
                    } else {
                        //如果有左侧子节点,递归调用insertNode方法继续找到树的下一层
                        insertNode(node.left, newNode);
                    }
                }else{
                    //如果节点的键比当前节点的键大,同时当前节点没有右侧子节点,就在那里插入新的节点
                    if(node.right === null){
                        node.right = newNode;
                    }else{
                        //如果又右侧子节点,递归调用insetNode方法
                        insertNode(node.right,newNode);
                    }
                }
            };
            //中序遍历所有节点
            //接受一个回调函数作为参数
            this.inOrderTraverse = function(callback){
                inOrderTraverseNode(root,callback);
            };
            var inOrderTraverseNode = function(node,callback){
                //检查以参数形式传入的节点是否为null
                if(node !== null){
                    //递归调用相同的函数来访问左侧子节点,对这个节点进行一些操作(callback)
                    inOrderTraverseNode(node.left,callback);
                    callback(node.key);
                    //访问右侧子节点
                    inOrderTraverseNode(node.right,callback);
                }
            };


            //先序遍历
            this.preOrderTraverse = function(callback){
                preOrderTraverseNode(root,callback);
            };
            var preOrderTraverseNode = function(node,callback){
                if(node!==null){
                    callback(node.key);
                    preOrderTraverseNode(node.left,callback);
                    preOrderTraverseNode(node.right,callback);
                }
            };

            //后序遍历
            this.postOrderTraverse = function(callback){
                postOrderTraverseNode(root,callback);
            };
            var postOrderTraverseNode = function(node,callback){
                if(node!==null){
                    postOrderTraverseNode(node.left,callback);
                    postOrderTraverseNode(node.right,callback);
                    callback(node.key);
                }
            };
            //寻找树的最小键
            this.min = function(){
                //传入树的根节点
                return minNode(root);
            };
            var minNode = function(node){
                if(node){
                    //遍历树的左边,知道找到输的最下层(最左端)
                    while(node &&node.left !== null){
                        node = nnode.left;
                    }
                    return node.key;
                }
                return null;
            };
            //寻找树的最大键
            this.max = function(){
                return maxNode(root);
            };
            var maxNode = function(node){
                if(node){
                    while (node&& node.right !== null){
                        node = node.right;
                    }
                    return node.key;
                }
                return null;
            };
            //声明search方法
            this.search = function(key){
                return searchNode(root,key);
                };
            var searchNode = function(node,key){
                //验证作为参数传入的node是否合法(不是null)如果是null,返回false
                if(node===null){
                    return false;
                }
                //要找的键比当前节点小,继续在左侧子树上搜索。要找的键比当前的节点哒,从右侧子节点开始搜索
                if(key<node.key){
                    return searchNode(node.left,key);
                }else if(key>node.key){
                    return searchNode(node.right,key);
                }else{
                    //要找的键和当前节点的键相等,返回true
                    return true;
                }
            };

            this.remove = function(key){
                root = removeNode(root,key);
            };

            var removeNode = function(node,key){
                //检测键是否存在于书中
                if(node===null){
                    return  null;
                }
                //在树中找到要移除的节点
                //要找的键比当前节点的值小,沿着树的左边找到下一个节点
                if(key<node.key){
                    node.left = removeNode(node.left,key);
                    return node;
                    //要找的键比当前节点的值大,沿着树的右边找到下一个节点
                }else if(key>node.key){
                    node.right = removeNode(node.right,key);
                    return node;
                }else{
                    //找到了要找的键,处理3种不同情况
                    //1.移除一个叶节点
                    if(node.left ===null&&node.right ===null){
                        node = null;
                        return null;
                    }
                    //2.移除有一个左侧或右侧子节点的节点
                    if(node.left === null){
                        node = node.right;
                        return node;
                    } else if(node.right ===null){
                        node = node.left;
                        return node;
                    }
                    //3.移除有两个子节点的节点
                    var aux = findMinNode(node.right);
                    node.key = aux.key;
                    node.right = removeNode(node.right,aux.key);
                    return node;
                }
            };


        }

        var tree = new BinarySearchTree();
        tree.insert(11);
        tree.insert(7);
        tree.insert(15);
        tree.insert(5);
        tree.insert(3);
        tree.insert(9);
        tree.insert(8);
        tree.insert(10);
        tree.insert(13);
        tree.insert(12);
        tree.insert(14);
        tree.insert(20);
        tree.insert(18);
        tree.insert(25);
        tree.insert(6);

        //创建一个回调函数
        function printNode(value){
            console.log(value);
        }
        //调用inOrderTraverse方法并将回调函数作为参数传入
        //tree.inOrderTraverse(printNode);
        //调用preOrderTraverse
        //tree.preOrderTraverse(printNode);
        //调用postOrderTraverse
        //tree.postOrderTraverse(printNode);
        console.log(tree.search(1)?'found':'not found');
        console.log(tree.search(8)?'found':'not found');


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值