二叉树

二叉排序树又叫二叉查找树或者二叉搜索树,它首先是一个二叉树,而且必须满足下面的条件:

若左子树不空,则左子树上所有结点的值均小于它的根节点的值;

若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

左、右子树也分别为二叉排序树;

没有键值相等的节点;

function BinaryTree(){
    var node = function(key){  //节点对象
        this.key = key; // 当前节点
        this.left = null; // 左边子节点
        this.right = null; // 右边子节点
    };
    
    var root = null;
    
    this.insert = function(key){ // 插入节点
        var newNode = new node(key);  // 创建节点
        if(root == null) // 判断根节点是否为空  如果为空则创建
            root = newNode; // 创建根节点
        else{ // 插入节点
            insertNode(root,newNode);
        }
    };
    
    var insertNode = function(node,newNode){ // 插入节点
        if(newNode.key < node.key){ //比较key的大小 如果新插入的节点小于当前节点  插入左边
            if(node.left === null){
                node.left = newNode;
            }else{  // 如果左边节点已经存在  重新执行
                insertNode(node.left,newNode);
            }
        }else{
            if(node.right === null){
                node.right = newNode;
            }else{  // 如果右边节点已经存在  重新执行
                insertNode(node.right,newNode);
            }
        }
        
    };
    
    // 遍历二叉树
    // 1中序遍历  得到当前节点后  进入左节点 如果存在 继续进入左节点  如果不存在 打印当前进入的左节点
    this.inOrderTraverse = function(callback){
        console.log(root);
        inOrderTraverseNode(root,callback); // 从root节点开始遍历
    };
    var inOrderTraverseNode = function(node,callback){
        if(node !== null){ //如果当前节点不为空
            inOrderTraverseNode(node.left,callback); // 遍历左节点 js是单线程 把这里执行完以后 才会执行下一步
            callback(node.key); // 打印当前节点
            inOrderTraverseNode(node.right,callback); // 遍历右几点
        }
    };
    
    // 2.前序遍历  打印当前遍历的节点 再进入左节点  然后再进入右节点
    this.preorderTraversal = function(callback){
        preorderTraversalNode(root,callback);
    };
    var preorderTraversalNode = function(node,callback){
        if(node !== null){
            callback(node.key);
            preorderTraversalNode(node.left,callback);
            preorderTraversalNode(node.right,callback);
        }
    };
    //3 后续遍历   得到当前节点 先访问左节点 再访问右节点  打印节点
    this.postOrderTraversal = function(callback){
        postOrderTraversalNode(root,callback);
    };
    var postOrderTraversalNode = function(node,callback){
        if(node !== null){
            postOrderTraversalNode(node.left,callback);
            postOrderTraversalNode(node.right,callback);
            callback(node.key);
        }
    };
    
    //  二叉树节点查找
    //1 查找最小值 一直进入左节点 如果当前节点没有左几点  当前节点key为最小值
    this.findMin = function(){
        findMinNode(root);
    };
    var findMinNode = function(node){
        if(node.left === null)
            console.log("最小值:"+node.key);
        else
            findMinNode(node.left);
    };
    
    //2. 查找最大值  一直进入右节点 如果当前节点没有右节点 当前节点key为最大值
    this.findMax = function(){
        console.log(root);
        findMaxNode(root);
    };
    var findMaxNode = function(node){
        if(node.right === null)
            console.log("最大值:"+node.key);
        else
            findMaxNode(node.right);
    };
    // 3.查找某一个值
    this.findVal = function(key){
        findValNode(root,key);
    };
    var findValNode = function(node,key){
        if(node !== null){
            if(node.key == key){
                console.log("查找到当前值:"+node.key);
                return node;
            }
            else if(node.key < key) // 当前节点值小于要查找的值
                findValNode(node.right,key);
            else // 当前节点值大于要查找的值
                findValNode(node.left,key);
        }else{ // node节点不存在
            console.log("没有当前值");    
            return false;
        }
    };
    
    // 删除节点  如果删除的节点有一个子节点  则将删除节点的父节点的lef或者right属性指向删除节点的子节点
    // 如果删除的节点有两个子节点, 则找出删除节点右边子节点的最小值 赋值给要删除的节点 然后再删除右边节点的最小值节点
    this.deleteNode = function(key){
        root = removeNode(root,key);
    };
    var removeNode = function(node,key){
        if(node === null)
            return null;
        if(node.key < key){ // 查找到当前值
            node.left = removeNode(node.left,key);
            return node;
        }else if(node.key < key){ // 当前节点值小于要查找的值
            node.right = removeNode(node.right,key);
            return node;
        }else{  // 值相同 删除节点
            if(node.left === null && node.right === null){  // 没有子节点
                node = null;
                return node;
            }
            if(node.left === null){ // 有一个右子节点
                node = node.right;
                return node;
            }
            if(node.right === null){ // 有一个左子节点
                node = node.left;
                return node;
            }
            if(node.left != null && node.right != null){ //有两个子节点
                let minNode = findVal(node.right);
                node.key = minNode.key; // 将最小值节点赋值给想要删除的节点
                removeNode(minNode,minNode.key); // 删除右子节点中的最小值节点
                return node;
            }
        }
    };
    var findVal = function(node){ // 查找右子节点中的最小值节点
        if(node.left == null){
            return node;
        }else{
            return findVal(node.left);
        }
    };
    
    
    
    
}

var nodes = [8,3,10,1,6,14,4,7,13];
var sortNodes = []; // 中序遍历
var proSortNodes = []; // 前序遍历
var postOrderSortNodes = []; // 后序遍历
var binaryTree = new BinaryTree();
nodes.forEach(function(item,i){ // 将数组nodes 插入二叉树  
    binaryTree.insert(item);
});
var callback = function(key){
    sortNodes.push(key);
}
var callback1 = function(key){
    proSortNodes.push(key);
}
var callback2 = function(key){
    postOrderSortNodes.push(key);
}
binaryTree.inOrderTraverse(callback);  // 中序遍历
console.log(sortNodes);

binaryTree.preorderTraversal(callback1); // 前序遍历
console.log(proSortNodes);

binaryTree.postOrderTraversal(callback2); // 后序遍历
console.log(postOrderSortNodes);


 
binaryTree.findMin(); // 查找最小值
binaryTree.findMax(); // 查找最大值
binaryTree.findVal(5); // 查询具体的值

binaryTree.deleteNode(1); // 删除节点

binaryTree.insert(9); // 添加元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值