zoukankan      html  css  js  c++  java
  • javascript数据结构——写一个二叉搜索树

    二叉搜索树就是左侧子节点值比根节点值小,右侧子节点值比根节点值大的二叉树。

    照着书敲了一遍。

    function BinarySearchTree(){
        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){
                //如果新节点值比当前节点小
                //则当前节点作为根节点,在当前节点左侧子节点寻找合适的位置
                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)
                }
            }
        }
    
        this.search = function(key){
            return searchNode(root,key)
        }
        var searchNode = function(node,key){
            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{
                return true
            }
        }
    
        //callback,调用遍历时作为参数传入
        function printNode(value){
            //打印节点值
            console.log(value)
        }
    
        this.inOrderTraverse = function(callback){
            //中序遍历
            inOrderTraverseNode(root,callback)
        }
        //中序遍历辅助函数
        var inOrderTraverseNode = function(node,callback){
            if(node != null){
                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(){
            //后序遍历
            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 = node.left
                }
    
                return node.key
            }else{
                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
            }else{
                return null
            }
        }
    
        //remove这个方法,我一开始没有搞懂为什么要令root = removeNode(root,key)
        //反复研究了几遍代码之后我才看明白了是为了更新节点
        //包括之后的removeNode方法
        //每一次递归更新子节点,最后还有return node更新父节点
        //因为此时父节点node的子节点已经不一样了,所以需要更新
        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{
                //key === node.key
                
                if(node.left === null && node.right === null){
                    //删除节点为叶子结点
                    node = null
                    return node
                }
                //删除的节点只有一个子节点
                if(node.left === null){
                    node = node.right
                    return node
                }else if(node.right === null){
                    node = node.left
                    return node
                }
    
                //删除的节点有两个子节点
                //从右侧子节点里寻找出最小的节点来继承当前节点
                //然后删除那个最小的右侧子节点
                var aux = findMinNode(node.right)
                node.key = aux.key
                node.right = removeNode(node.right,aux.key)
                return node
            }
        }
        var findMinNode = function(node){
            if(node){
                while(node && node.left!=null){
                    node = node.left
                }
    
                return node
            }else{
                return null
            }
        }
    }
  • 相关阅读:
    Django学习路10_创建一个新的数据库,指定列名并修改表名
    设计模式_单例模式的懒汉式实例化
    设计模式_理解单例设计模式
    Django学习路9_流程复习
    Django学习路8_学生表和班级表级联并相互查询信息
    Django学习路7_注册app到能够在页面上显示app网页内容
    es6基础:类、继承、重写
    简单的下拉刷新
    callback&&callback()
    转 五大浏览器四大内核
  • 原文地址:https://www.cnblogs.com/minz/p/6090963.html
Copyright © 2011-2022 走看看