JS:遍历二叉树(1)——两种递归思路

前中后序是遍历二叉树过程中处理每一个节点的三个特殊时间点
二叉树的所有问题,就是让你在前中后序位置注入巧妙的代码逻辑,去达到自己的目的。
在这里插入图片描述
后序位置的代码不仅可以获取参数数据,还可以获取到子树通过函数返回值传递回来的数据。一旦你发现题目和子树有关,那大概率要给函数设置合理的定义和返回值,在后序位置写代码了

两种解题思路

二叉树题目的递归解法可以分两类思路,第一类是遍历一遍二叉树得出答案,第二类是通过分解问题计算出答案,这两类思路分别对应着 回溯算法核心框架 和 动态规划核心框架。

104. 二叉树的最大深度

方法一: 遍历一遍二叉树,用一个外部变量记录每个节点所在的深度,取最大值就可以得到最大深度,这就是遍历二叉树计算答案的思路。
利用:前序位置是进入一个节点的时候,后序位置是离开一个节点的时候

出现迷之问题,执行不出错,提交出错。目前唯一办法,把辅助函数写在主函数体内,这样才能正确使用全局变量

// 主函数 
var maxDepth = function(root) {
    let res = 0;
    let depth = 0; // 记录遍历到的节点的深度
    // 二叉树遍历框架
    function traverse(root) {
        if(root == null) {
            // 叶子节点深度大于非叶子节点
            res = Math.max(res, depth);
            return;
        }
        depth++;
        traverse(root.left)
        traverse(root.right)
        depth--;
    }
    traverse(root);
    return res;
};


方法二: 二叉树的最大深度可以通过子树的最大高度推导出来,这就是分解问题计算答案的思路。
利用:递归函数的定义算出左右子树的最大深度,然后推出原树的最大深度,主要逻辑自然放在后序位置。

var maxDepth = function(root) {
    if (root == null) {
		return 0;
	}
	// 利用定义,计算左右子树的最大深度
	let leftMax = maxDepth(root.left);
	let rightMax = maxDepth(root.right);
	// 整棵树的最大深度等于左右子树的最大深度取最大值,
    // 然后再加上根节点自己
	let res = Math.max(leftMax, rightMax) + 1;

	return res;
};

543. 二叉树的直径

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
在这里插入图片描述
在这里插入图片描述

每一条二叉树的「直径」长度,就是一个节点的左右子树的最大深度之和。

还是一样,全局变量写在主函数内。但让我找到了原因参考类似问题: LeetCode 提交后运行时代码中的全局变量并没有成功初始化,保险起见,需要在函数中重新初始化全局变量。

var diameterOfBinaryTree = function(root) {
    function maxDepth(root) {
        if(root == null) return 0;
        let left = maxDepth(root.left)
        let right = maxDepth(root.right)
        let depth = Math.max(left, right) + 1
        let len = left + right // 子树深度等于跟节点到叶子的边
        maxlen = Math.max(maxlen, len)
        return depth
    }
    let maxlen = 0
    maxDepth(root)
    return maxlen;
};

把函数,全局变量写在外面。

let maxlen = 0 
function maxDepth(root) {
        if(root == null) return 0;
        let left = maxDepth(root.left)
        let right = maxDepth(root.right)
        let depth = Math.max(left, right) + 1
        let len = left + right // 子树深度等于跟节点到叶子的边
        maxlen = Math.max(maxlen, len)
        return depth
    }
var diameterOfBinaryTree = function(root) {
    maxlen = 0 // 重新初始化全局变量
    maxDepth(root)
    return maxlen;
};

102. 二叉树的层序遍历

二叉树题型主要是用来培养递归思维的,而层序遍历属于迭代遍历,这里就过一下代码框架吧

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
在这里插入图片描述

var levelOrder = function(root) {
    if(root == null) return [];
    let queue = [], ans = []
    queue.push(root)
    while(queue.length) {
        let temp = [], curlen = queue.length
        for(let i=0; i<curlen; i++){
            let node = queue.shift()
            temp.push(node.val)
            node.left && queue.push(node.left) // 代码功底
            node.right && queue.push(node.right)
        }
        ans.push(temp)
    }
    return ans;
};

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值