JavaScript数据结构之树

是一种非顺序的数据结构,对于存储需要快速查找的数据非常有用。
JavaScript数据结构之树_第1张图片
位于树顶部的节点称为根节点。树中的节点分为内部节点和外部节点,至少有一个子节点的节点为内部节点,没有子节点的节点为外部节点或者叶节点
子树是由节点和它的子节点构成,例如上面的节点E,K,L构成一棵子树。
节点深度取决于其祖先节点的数量,比如节点E的深度为2,它有两个祖先节点A和B。
树的高度取决于所有节点深度的最大值。一棵树可以被分解成层级,根节点在第0层,节点的层数也是其的深度。

二叉树和二叉搜索树

在二叉树中,最多只能有两个子节点(左子节点和右子节点)。
二叉搜索树是二叉树的一种,左子节点存储比父节点小的值,右子节点存储比父节点大或者相等的值。

和链表一样,二叉搜索树也是通过指针来表示节点之间的关系。二叉搜索树具有两个指针,一个指向左子节点,另一个指向了右子节点。

let BinarySearchTree=(function(){
    class Node{
        constructor(key){
            this.key = key
            this.left = null
            this.right = null 
        }
    }
    class BinarySearchTree{
        constructor(){
            this.root = null
        }
        insert(key){
            var newNode = new Node(key)
            if(this.root === null){
                this.root = newNode
            }else{
                this.insertNode(this.root,newNode)
            }
        }
        insertNode(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)
                }
            }
        }
        inOrderTraverse(callback){
            this.inOrderTraverseNode(this.root,callback)
        }
        inOrderTraverseNode(node,callback){ // 左根右
            if(node!==null){
                this.inOrderTraverseNode(node.left,callback)
                callback(node.key)
                this.inOrderTraverseNode(node.right,callback)
            }
        }
        preOrderTraverse(callback){
            this.preOrderTraverseNode(this.root,callback)
        }
        preOrderTraverseNode(node,callback){ // 根左右
            if(node!==null){
                callback(node.key)
                this.preOrderTraverseNode(node.left,callback)
                this.preOrderTraverseNode(node.right,callback)
            }
        }
        postOrderTraverse(callback){
            this.postOrderTraverseNode(this.root,callback)
        }
        postOrderTraverseNode(node,callback){ // 左右根
            if(node!==null){
                this.postOrderTraverseNode(node.left,callback)
                this.postOrderTraverseNode(node.right,callback)
                callback(node.key)
            }
        }
        min(){
            return this.minNode(this.root)
        }
        minNode(node){
            if(node){
                while(node && node.left!==null){
                    node=node.left
                }
                return node.key
            }
            return null
        }
        max(){
            return this.maxNode(this.root)
        }
        maxNode(node){
            if(node){
                while(node && node.right!==null){
                    node=node.right
                }
                return node.key
            }
            return null
        }
        print(value){
            console.log(value)
        }
        search(key){
            return this.searchNode(this.root,key)
        }
        searchNode(node,key){
            if(node === null){
                return false
            }
            if(key<node.left){
                return this.searchNode(node.left,key) // 方法进栈
            }else if(key>node.right){
                return this.searchNode(node.right,key)
            }else{
                return true;
            }
        }
        remove(key){
            this.root=this.removeNode(this.root,key)
        }
        removeNode(node,key){ // 删除节点
            if(node === null){
                return null
            }
            if(key<node.key){
                node.left=this.removeNode(node.left,key) // 方法进栈
                return node
            }else if(key>node.key){
                node.right=this.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
                } else if (node.right === null){ // 删除节点只有左节点
                    node = node.left
                    return node
                }
                var aux = this.finMinNode(node.right) // 左右节点都存在,就找到右子树中最小的节点当作替换节点。
                node.key = aux.key
                node.right = this.removeNode(node.right,aux.key) // 删除替换节点
                return node;
            }
        }
        finMinNode(node){
            while(node && node.left!==null){
                node = node.left
            }
            return node;
        }
    }
    return BinarySearchTree
} ())
var tree = new BinarySearchTree()
tree.insert(5)
tree.insert(11)
tree.insert(12)
tree.insert(5)
tree.insert(6)
tree.inOrderTraverse(tree.print) // 5 5 6 11 12
tree.preOrderTraverse(tree.print) // 5 11 5 6 12
tree.postOrderTraverse(tree.print) // 6 5 12 11 5

你可能感兴趣的:(javascript,数据结构,数据结构,二叉树,javascript)