• 关于二叉树的算法(JavaScript)


    二叉树的遍历

    前序遍历

    中左右

    function preorderTraversal( root ) {
        let res = []
        preOrder(root)
        return res
        function preOrder(node){
            if(node === null) return
            res.push(node.val)
            preOrder(node.left)
            preOrder(node.right)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    中序遍历

    左中右

    function inorderTraversal( root ) {
        let res = []
        inorderTravese(root)
        return res
        function inorderTravese(node){
            if(node === null) return null
            inorderTravese(node.left)
            res.push(node.val)
            inorderTravese(node.right)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    后序遍历

    左右中

    function postorderTraversal( root ) {
        let res = []
        postorderTraverse(root)
        return res
        function postorderTraverse(node){
            if(node === null) return
            postorderTraverse(node.left)
            postorderTraverse(node.right)
            res.push(node.val)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    层序遍历

    function levelOrder( root ) {
        const res = [], queue = []
        if(root === null) return null
        queue.push(root)
        while(queue.length){
            let length = queue.length
            const curLevel = []
            while(length --){
                let node = queue.shift()
                curLevel.push(node.val)
                node.left && queue.push(node.left)
                node.right && queue.push(node.right)
            }
            res.push(curLevel)
        }
        return res
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    二叉树的最大深度

    二叉树的最大深度
    输入:{1,2}
    返回值:2
    方法:利用层序,有几层深度就是多少

    function maxDepth( root ) {
        let res = 0
        if(root === null) return res
        const queue = []
        queue.push(root)
        while(queue.length){
            let len = queue.length
            while(len --){
                let node = queue.shift()
                node.left && queue.push(node.left)
                node.right && queue.push(node.right)
            }
            res ++
        }
        return res
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    // 递归方法
    function maxDepth( root ) {
        // write code here
        if(root === null) return 0
        let max = 0
        if(root.left){
            max = Math.max(max, maxDepth(root.left))
        }
        if(root.right){
            max = Math.max(max, maxDepth(root.right))
        }
         
        return max + 1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    二叉树中和为某一值的路径

    二叉树中和为某一值的路径
    输入:{5,4,8,1,11,#,9,#,#,2,7},22
    返回值:true
    方法:递归

    function hasPathSum(root, sum) {
        // write code here
        // 空树
        if (root === null) return false
        function dfs(node, sum) {
            if (node === null) return false
            // 已经遍历到叶子节点
            if (node.left === null && node.right === null && node.val === sum) {
                return true
            }
            return dfs(node.left, sum - node.val) || dfs(node.right, sum - node.val)
        }
        return dfs(root, sum)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    二叉搜索树与双向链表

    二叉搜索树与双向链表
    方法:利用中序遍历

    function Convert(pRootOfTree) {
        // head:头节点
        // pre:记录上一节点
        let head = null, pre = null
        // 中序遍历
        function traversal(node) {
            if (node === null) {
                return
            }
            traversal(node.left)
            // 处理当前节点
            // 如果是前序遍历的第一个节点,head始终指向该节点
            if (node.left === null && head === null) {
                head = node
                pre = node
            } else {
                // 前一节点的右指针指向当前节点
                // 当前节点的左指针指向前一节点
                // 更新pre
                pre.right = node
                node.left = pre
                pre = node
            }
            traversal(node.right)
        }
        traversal(pRootOfTree)
        return head
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    对称二叉树

    对称二叉树

    function isSymmetrical(pRoot) {
        function isSym(left, right) {
            // 没有子节点
            if (left === null && right === null) {
                return true
            }
            // 只有一个节点为空
            if (left === null || right === null) {
                return false
            }
            // 数值不相等
            if (left.val !== right.val) {
                return false
            }
            return isSym(left.left, right.right) && isSym(left.right, right.left)
        }
        if (pRoot === null) {
            return true
        }
        return isSym(pRoot.left, pRoot.right)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    合并二叉树

    合并二叉树
    都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。

    function mergeTrees( t1 ,  t2 ) {
        if(t1 === null) return t2
        if(t2 === null) return t1
        t1.val = t1.val + t2.val
        t1.left = mergeTrees(t1.left, t2.left)
        t1.right = mergeTrees(t1.right, t2.right)
        return t1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    二叉树的镜像

    二叉树的镜像

    function Mirror( pRoot ) {
        if(pRoot === null){
            return null
        }
        let tmp = pRoot.left
        pRoot.left = pRoot.right
        pRoot.right = tmp
        Mirror(pRoot.left)
        Mirror(pRoot.right)
        return pRoot
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    判断

    判断是不是二叉搜索树

    判断是不是二叉搜索树
    方法:中序遍历,然后判断是否是递增

    function isValidBST(root) {
        // 中序遍历,判断是否递增
        function travel(node) {
            if (node) {
                travel(node.left)
                arr.push(node.val)
                travel(node.right)
            }
        }
        let arr = []
        travel(root)
        for (let i = 1; i < arr.length; i++) {
            if (arr[i] <= arr[i - 1]) {
                return false
            }
        }
        return true
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    判断是不是完全二叉树

    判断是不是完全二叉树
    方法:利用层序遍历,如果是完全二叉树,直到最后才会遇到null

    function isCompleteTree( root ) {
        let queue = []
        queue.push(root)
        // 标记是否遇到空节点
        let flag =false
        while(queue.length){
            const node = queue.shift()
            // 遇到空节点则标记成true
            if(node === null) {
                flag = true
            } else {
                // 当前节点不是空节点,但flag是true,则说明不是完全二叉树
                if(flag === true) {
                    return false
                }
                queue.push(node.left)
                queue.push(node.right)
            }
        }
        return true
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    判断是不是平衡二叉树

    判断是不是平衡二叉树
    方法:求出左右子树的最大深度,绝对值小于等于1。特别注意:左右子树也要满足平衡二叉树

    function IsBalanced_Solution(pRoot) {
        if (pRoot === null) return true
        // 求最大深度
        function maxDeep(node) {
            let max = 0
            if (node.left) {
                max = Math.max(max, maxDeep(node.left))
            }
            if (node.right) {
                max = Math.max(max, maxDeep(node.right))
            }
            return max + 1
        }
        // 求左右子树的最大深度
        let leftDeep = 0, rightDeep = 0
        if (pRoot.left) {
            leftDeep = maxDeep(pRoot.left)
        }
        if (pRoot.right) {
            rightDeep = maxDeep(pRoot.right)
        }
        // 左右子树的最大深度差小于等于1 且 左右子树都满足平衡二叉树
        return Math.abs(leftDeep - rightDeep) <= 1
            && IsBalanced_Solution(pRoot.left)
            && IsBalanced_Solution(pRoot.right)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    最近公共祖先

    二叉树的最近公共祖先

    二叉树的最近公共祖先

    方法:如果left和right的返回值都不为空,则返回root;否则返回不为空的那个。

    function TreeNode(val) {
       this.val = val;
       this.left = this.right = null;
    }
    
    var lowestCommonAncestor1 = function(root, p, q){
        function travelTree(node, p, q){
            if(node === null || node === p || node === q){
                return node
            }
            let left = travelTree(node.left, p, q)
            let right = travelTree(node.right, p, q)
            if(left !== null && right !== null){
                return node
            }
            if(left === null){
                return right
            }
            return left
        }
        return travelTree(root, p, q)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    二叉搜索树的最近公共祖先

    二叉搜索树的最近公共祖先
    方法:如果val大于p和q的val,则从节点的左子树开始找

    var ancestor = function(root, p, q){
        while (root) {
            if(root.val > p.val && root.val > q.val){
                root = root.left
            }else if(root.val < q.val && root.val < p.val){
                root = root.right
            }else{
                return root
            }
        }
        return null
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    构建二叉树

    从前序与中序遍历序列构造二叉树

    从前序与中序遍历序列构造二叉树

    var buildTreefromPreInorder = function(preorder, inorder){
        if(!preorder.length) return null
        let root = new TreeNode(preorder[0])
        let mid = inorder.findIndex(number => number === root.val)
        root.left = buildTreefromPreInorder(preorder.slice(1, mid + 1), inorder.slice(0, mid))
        root.right = buildTreefromPreInorder(preorder.slice(mid + 1, preorder.length), inorder.slice(mid + 1, inorder.length))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    从中序与后序遍历序列构造二叉树

    106. 从中序与后序遍历序列构造二叉树

    // 中序+后序
    var buildTreefromPostInorder = function(inorder, postorder){
        if(!postorder.length) return null
        // 构建根节点
        let root = new TreeNode(postorder[postorder.length - 1])
        // 寻找分割点
        let index = inorder.findIndex(number => number === root.val)
        root.left = buildTreefromPostInorder(inorder.slice(0,index), postorder.slice(0,index))
        root.right = buildTreefromPostInorder(inorder.slice(index + 1, inorder.length), postorder.slice(index, postorder.length - 1))
        return root
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    微信小游戏是个人尝试做游戏最好的选择
    手把手教学一文安装Keil5(MDK)
    编译正常运行,打jar包运行报错(找不到文件路径)
    2源码安装网络协议
    Springboot2.7.0 集成pagehelper问题解决
    linux添加了公钥后,ssh登录却还需要密码
    Java项目:springboot医院管理系统
    Postman报错:Error:‌ NETERR:‌ getaddrinfo ENOTFOUND localhost
    走进Kaggle的未知领域:性别和年龄推断算法解析
    【opencv450-samples】图像分割grabcut算法
  • 原文地址:https://blog.csdn.net/qq_42037746/article/details/125485944