Python实现二叉树添加节点失效root始终为None,求问题排查
问题排查与修复
第一个实现的错误原因
你的_add方法缺少非空根节点的返回逻辑:
Python的函数如果没有显式写return语句,默认会返回None。你当前的代码只有当传入的root为空时,才返回了新创建的节点;当root不为空时,只处理了左右子树的递归赋值,没有把当前root返回给上层调用方,会导致两个问题:
- 插入第二个及以后的节点时,上层的
root.left/root.right会被赋值为None,直接丢失子树 - 当根节点已经存在时,调用
_add返回None,你用self.root = self._add(...)就会把原来的根节点覆盖为空
这也解释了为什么你在C/Java里的同逻辑代码能运行:你之前的实现要么用了指针/引用传递直接修改节点地址,要么补了非空节点的返回逻辑。Python没有引用传递,函数内对参数变量的重新赋值不会影响外层变量,必须通过返回值赋值给外层变量才能生效。
修复方法
给_add方法末尾加上非空节点的返回语句即可:
def _add(self,data,root): if root is None: root = Node(data) return root elif data <= root.data: root.left = self._add(data, root.left) else: root.right = self._add(data,root.right) # 新增:非空节点将自身返回给上层调用 return root
修复后不管你是直接调用self._add(data,self.root)还是写self.root = self._add(data,self.root)都能正常工作,因为根节点存在的情况下返回的还是原根节点,不会出现覆盖为空的问题。
第二个实现的错误原因
你写的add是Tree类的实例方法,定义只接受self和data两个参数,但是你递归调用的时候写了self.add(self.root.left,data),相当于给add传了三个参数(第一个是默认传入的实例本身self,加上你手动写的self.root.left和data两个参数),自然会报参数数量不匹配的错误。
而且这个实现逻辑本身有问题:add方法操作的是当前Tree实例的root属性,你递归的时候没法直接指定要操作的子树根节点,必须要拆分出第一个版本里的私有_add递归方法来接收子节点参数才能正常递归。
内容的提问来源于stack exchange,提问作者mehekek
相关产品推荐
相关产品推荐

