如何理解求解二叉树直径的Python递归代码的运行逻辑?
二叉树直径代码运行原理解析
这个解法的核心逻辑非常好懂,你只需要先明确两个基础定义:
- 任意节点的高度:从当前节点向下走到最远的叶子节点,路径上的总节点数(空节点高度为0,叶子节点自身高度为1)
- 任意节点对应的潜在直径:如果把当前节点当作最长路径的中间最高点,那么路径总长度就是「左子树高度 + 右子树高度 + 1(当前节点自身)」,这个路径的两端恰好是左右子树各一个叶子节点,完全符合树直径的定义
整棵树的直径,就是所有节点对应的潜在直径里的最大值。你猜测的完全正确:所有数值计算都是在递归出栈(也就是后序遍历)阶段执行的,因为必须先拿到左右子树的高度,才能计算当前节点的高度和潜在直径。
代码执行流程拆解
calculate_height 函数的作用
这个函数同时做了两件事:
- 递归计算当前节点的高度,返回给上层父节点使用
- 计算当前节点对应的潜在直径,更新全局记录的最大直径
self.treeDiameter
拿第一个测试用例走一遍流程
第一个测试用例的树结构如下:
1 / \ 2 3 / / \ 4 5 6
递归是深度优先顺序,先走左子树:
- 调用
calculate_height(1),先递归执行左子树calculate_height(2) - 进入节点2的逻辑,先递归执行左子树
calculate_height(4) - 进入节点4的逻辑,递归左子树为空返回0,递归右子树为空返回0
- 计算当前节点潜在直径:
0+0+1=1,全局最大直径更新为1 - 返回节点4的高度:
max(0,0)+1=1
- 计算当前节点潜在直径:
- 回到节点2的逻辑,递归右子树为空返回0
- 计算当前节点潜在直径:
1+0+1=2,全局最大直径更新为2 - 返回节点2的高度:
max(1,0)+1=2
- 计算当前节点潜在直径:
- 回到节点1的逻辑,递归执行右子树
calculate_height(3) - 进入节点3的逻辑,先递归左子树
calculate_height(5)- 节点5左右子树都为空,返回高度1,潜在直径为1,全局最大直径保持2
- 再递归节点3的右子树
calculate_height(6),返回高度1,潜在直径为1,全局最大直径保持2 - 回到节点3的逻辑,计算当前节点潜在直径:
1+1+1=3,全局最大直径更新为3- 返回节点3的高度:
max(1,1)+1=2
- 返回节点3的高度:
- 回到节点1的逻辑,计算当前节点潜在直径:
2+2+1=5,全局最大直径更新为5- 返回节点1的高度:
max(2,2)+1=3
- 返回节点1的高度:
最终返回的全局最大直径就是5,和代码第一个输出结果完全一致。
另外补充一点:代码里的if leftTreeHeight is not None and rightTreeHeight is not None判断是冗余的,因为空节点固定返回0,永远不会为None,删掉这个判断也不会影响运行结果。你最开始想的遍历节点计数的思路本质和这个解法是一致的,递归返回的高度本身就是逐层计数的结果,每向上返回一层高度加1,就是你说的计数加1的逻辑。
内容的提问来源于stack exchange,提问作者Michael Torres
相关产品推荐
相关产品推荐

