为何BST单孩子根节点调用remove方法无法被删除?
二叉搜索树删除根节点失效的原因及解决办法
问题核心原因
你在remove方法里写的self = self.right根本没法修改根节点——因为Python类方法里的self是个局部参数,它只是指向当前实例的一个变量。当你给self重新赋值时,只是把这个局部变量的指向换成了右子节点,但原来的BST实例(也就是外部代码持有的那个根对象)完全没变化。
举个实际场景:外部代码是tree = BST(1),调用tree.remove(1)时,方法里的self一开始指向tree对应的1节点;执行self = self.right后,方法里的self指向2节点,但外部的tree还是指向原来的1节点,所以根节点自然没变。
而非根节点的情况(比如删除2),你用parent.right = current.right能生效,是因为parent是原来树中节点的引用,修改它的right属性直接改变了树的结构,不是修改局部变量。
解决办法
要替换根节点,不能给self赋值,得直接修改当前根实例的属性:
class BST: def __init__(self, value): self.value = value self.left = None self.right = None def remove(self, value): current = self parent = None # 第一步:找到要删除的节点和它的父节点 while current is not None and current.value != value: parent = current if value > current.value: current = current.right else: current = current.left if current is None: return # 没找到目标节点,直接返回 # 情况1:要删除的节点左子树为空 if current.left is None: if parent is None: # 处理根节点的情况:直接把根的属性替换成右子节点的 if current.right is None: # 单节点树,按要求不执行操作 return self.value = current.right.value self.left = current.right.left self.right = current.right.right else: # 非根节点,通过父节点指向右子树 if parent.left == current: parent.left = current.right else: parent.right = current.right # 其他情况(左子树非空)的处理逻辑...
这样当删除根节点且左子树为空时,直接修改self(也就是根实例)的value、left、right属性,就能真正替换掉根节点。
补充说明
如果你的BST设计允许remove方法返回新的根节点,也可以让方法返回current.right(当根节点左空时),然后外部代码用tree = tree.remove(1)来更新根,但这种方式不符合大多数BST类的状态修改习惯,还是直接修改实例属性的方式更合理。
内容的提问来源于stack exchange,提问作者Karina
相关产品推荐
相关产品推荐

