Python二叉树剪枝:两种实现差异及关键赋值语句解析
二叉树剪枝代码差异分析:为什么那两行赋值如此关键
首先明确剪枝目标:移除所有值为0且没有子节点的节点。我们来拆解两个版本的核心差异,以及那两行赋值的作用。
第一个版本的正确逻辑
这个版本的递归是自上而下+自下而上的完整流程:
- 先递归处理左、右子树,把处理后的子树根节点重新赋值给当前节点的
left和right。 - 再判断当前节点是否符合剪枝条件(值为0且左右子节点都为空),符合则返回
None(表示当前节点要被剪掉),否则返回当前节点。
这里的root.left = self.pruneTree(root.left)和root.right = self.pruneTree(root.right)是核心,它们做了两件关键事:
- 更新当前节点的子指针:递归处理子树后,返回的是剪枝后的子树(可能是
None),把这个结果赋值给当前节点的子指针,相当于把剪掉的子节点从当前节点的引用中彻底移除。 - 传递剪枝结果给上层:当前节点处理完后,返回的结果会被上层节点的
left或right接收,从而层层向上更新整个树的结构,确保所有无效节点都被彻底清理。
举个实际例子:如果当前节点的左子节点是一个值为0的叶子节点,递归处理左子树时会返回None,赋值给root.left后,当前节点的左指针就变成了None,后续判断当前节点的条件时就能正确识别左右子节点的状态。
第二个版本的错误原因
这个版本的问题出在没有更新子指针,且局部赋值无效:
- 只调用了
self.pruneTree(root.left)但没有赋值,意味着递归处理完左子树后,当前节点的left指针依然指向原来的子节点。哪怕子节点被递归逻辑标记为None,当前节点的引用没更新,后续判断root.left is None时依然是False,无法正确触发剪枝条件。 - 当判断当前节点要剪枝时,
root = None只是修改了函数内部的局部变量root,不会影响上层父节点的子指针。上层节点依然指向原来的这个节点,导致该节点根本没被从树中移除。
比如:父节点A的左子节点是B(值0的叶子节点),第二个版本处理B时,虽然在函数里把B设为None,但A的left还是指向原来的B节点,所以A的左子节点依然存在,剪枝完全没生效。
总结
root.left = self.pruneTree(root.left)和root.right = self.pruneTree(root.right)的关键在于:
它们是递归过程中连接上下层树结构的桥梁,既让当前节点能拿到剪枝后的子树状态,也让上层节点能接收当前节点的剪枝结果,最终实现整个树的无效节点彻底移除。
内容的提问来源于stack exchange,提问作者Yuva Sri
相关产品推荐
相关产品推荐

