二叉树递归中return root的作用?以LC226翻转二叉树为例
return root的本质解析 一、return root返回给谁?
每次递归调用的return结果,都会返回给发起这次调用的上层函数上下文。比如你代码里的self.invertTree(root.left),这个调用的返回值会回到当前正在执行的invertTree函数里——只不过你的代码里没有接收这个返回值,但不代表它没有意义。
二、为什么中间递归步骤也需要返回?
1. 完成递归终止的逻辑闭环
当root == None时返回root,这是递归的终止条件,用来告诉上层调用:“这个子树是空的,没有需要处理的节点”。如果没有这个返回,递归遇到空节点时会默认返回None,虽然结果可能对,但不符合函数的返回值声明,也会破坏递归的逻辑完整性。
2. 适配不同场景的函数接口
你的代码是原地修改二叉树结构:交换左右指针后递归处理子树。这时候看起来好像没用到返回值,但如果换成构造新树的场景(比如不修改原树,生成一个翻转后的新树),返回值就成了核心:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: if not root: return None # 创建新节点,不修改原树 new_node = TreeNode(root.val) # 递归处理原树的右子树,返回结果作为新节点的左子树 new_node.left = self.invertTree(root.right) # 递归处理原树的左子树,返回结果作为新节点的右子树 new_node.right = self.invertTree(root.left) # 返回当前构造好的新子树根节点给上层 return new_node
这里每一层递归的返回值,都是上层用来构建父节点左右子树的关键。即使是原地修改的场景,return root也是保持函数接口的一致性——不管处理的是哪个层级的子树,函数都返回该子树处理后的根节点,符合函数签名要求,也让代码更具扩展性。
3. 递归调用的天然要求
递归函数的每一次调用,本质上都是一个独立的函数执行过程。每个过程都需要有明确的返回结果,才能让上层调用确认当前子树的处理状态。哪怕你的代码里没有显式使用这个返回值,它也是递归逻辑完整的一部分——否则当递归回溯时,上层调用无法确认当前子树是否处理完成。
三、回到你的翻转二叉树代码
你的代码里,self.invertTree(root.left)返回的是处理后的左子树根节点(也就是原来的右子树翻转后的根),但因为是原地修改,root.left已经指向了这个处理后的节点,所以不需要额外赋值。但函数依然要返回root,这是为了:
- 符合函数的返回值类型声明;
- 保持递归逻辑的一致性,让每一层调用都有明确的输出;
- 如果后续需要调整代码逻辑(比如改成非原地修改),不需要大幅改动递归的返回逻辑。
内容的提问来源于stack exchange,提问作者Rahul

