二叉搜索树javascript

定义

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

插入节点

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)
         
     }
 }

先序遍历(非递归)

 //先序遍历非递归
 //非递归方式的话,头节点先入栈,然后出栈并处理,出栈的同时右节点入栈,
 //左节点入栈,因为是先处理的左节点,所以右节点先入栈,然后循环直到栈为空
 BinarySearchTree.prototype.preTraversal = function(head){
     /*
     先序遍历思想:
     */
     if(head != null){
         let stack = []
         stack.push(head)
         while(stack.length!=0){
             head = stack.pop()
             console.log(head.key)
             if(head.right!=null) stack.push(head.right)
             if(head.left!=null) stack.push(head.left)
         }
     }
 }

中序遍历(递归)

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

BinarySearchTree.prototype.midOrderTraversalNode = function(node,handler){
    if(node != null){
        this.midOrderTraversalNode(node.left,handler)
        handler(node.key)
        this.midOrderTraversalNode(node.right,handler)
    }
}

中序遍历(非递归)

//中序遍历非递归
BinarySearchTree.prototype.midTraversal = function(head){
    /*
    从根节点开始进栈,然后左节点进栈,继续左节点入栈,直到左节点为空,然后出栈
    出栈的节点的右节点进栈,然后右节点左节点一直进栈,直至为空,一直这样循环
    */
   if(head!=null){
       let s = []
       while(s.length!=0||head!=null){
           if(head!=null){
               s.push(head)
               head= head.left
           }else{
               head = s.pop()
               console.log(head.key)
               head = head.right
           }
       }
   }
}

后序遍历(递归)

//后续遍历
BinarySearchTree.prototype.aftOrderTraversal = function(handler){
    this.aftOrderTraversalNode(this.root,handler)
}

BinarySearchTree.prototype.aftOrderTraversalNode = function(node,handler){

    if(node != null){
        this.aftOrderTraversalNode(node.left,handler)
        
        this.aftOrderTraversalNode(node.right,handler)
        handler(node.key)
    }
}

后序遍历(非递归)

BinarySearchTree.prototype.aftTraversal = function(head){
/**
 * 思路:头节点进栈。
 * 栈一出栈,出栈的节点进栈2,如果出栈的节点有左节点就进栈1,有右节点就进栈1,循环直至栈1为空
 */
if(head!=null){
    let s1 = []
    let s2 = []
    s1.push(head)
    while(s1.length!=0){
        head = s1.pop()
        s2.push(head)
        if(head.left!=null) s1.push(head.left)
        if(head.right!=null) s1.push(head.right)
    }
    while(s2.length!=0){
        console.log(s2.pop().key)
    }

}

获取最大值

BinarySearchTree.prototype.getMaxNode = function(){
    let node = this.root
    while(node.right != null){
        node = node.right
    }

    return node.key
}

获取最小值

BinarySearchTree.prototype.getMinNode = function(){
    let node = this.root
    while(node.left != null){
        node = node.left
    }

    return node.key
}

递归查找key

//递归查找key
BinarySearchTree.prototype.search = function(key){
    return this.searchNode(this.root,key)
}
BinarySearchTree.prototype.searchNode = function(node,key){
    //如果传入的node为 null,那么推出递归
    if(node === null){
        return false
    }

    //判断node节点的值和传入的key值
    if(node.key > key){
        return this.searchNode(node.left,key)
    }else if(node.key < key){
        return this.searchNode(node.right,key)
    }else{
        return true
    }
}

while查找key

//while查找key
BinarySearchTree.prototype.searchByWhile = function(key){
    let node = this.root

    while(node!=null){
        if(key < node.key){
            node = node.left
        }else if(key > node.key){
            node = node.right
        }else{
            return true
        }

    }
    return false
}

删除节点

//删除节点
BinarySearchTree.prototype.remove = function(key){
    //1.寻找要删除的节点
    //1.1 定义变量,要删除节点,需要3个变量
    let current = this.root
    let parent = null
    let isLeftChild = true//记录current是parent的左子节点还是右子节点

    //1.2开始查找删除节点
    while(current.key!=key){
        parent = current
        if(key < current.key){
            isLeftChild = true
            current = current.left
        }else{
            isLeftChild = false
            current = current.right
        }

        //在某种情况下,已经找到最后的节点了,依然没有找到key
        if(current == null) return false
    }

    //2.根据对应的情况删除节点
    //2.1删除的是叶子节点
    if(current.right == null && current.left==null){
        if(current == this.root){//删除的是根节点
            this.root = null

        }else if(isLeftChild){
            parent.left = null
        }else{
            parent.right = null
        }
    }

    //2.2删除的有一个子节点
    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
        }
    }

    //2.3有两个节点
    else{
        //获得后继节点
        var successer = this.getSuccssor(current)

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


    }
    return true


}

//找后继的方法
BinarySearchTree.prototype.getSuccssor = function(delNode){
    //1.定义变量,保存找到的后继
    //找右子节点的左节点就是要删除节点的后继,也就是要删除节点的右边全部节点中值最接近要删除节点的节点
    let successer = delNode//后继节点
    let current = delNode.right
    let successerParent = delNode//保存要找到的后继节点的父节点

    //2.循环查找
    while(current != null){
        successerParent = successer
        successer = current
        current = current.left
    }
    //如果后继节点不是删除节点的右节点
    if(successer != delNode.right){
        successerParent.left = successer.right
        successer.right = delNode.right
    }
    
    return successer
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值