我想知道为什么我的BST删除方法不起作用。我已经实现了递归,并且由于某些原因,没有节点被删除。
def delete(self,node, val):
if(node == None):
return None
if(val < node.data):
node.left = self.delete(node.left,val)
elif( val > node.data):
node.right = self.delete(node.right,val)
else:
if(node.right ==None and node.left ==None):
return None
elif(node.left==None): # delete the node holding 1 child
node=node.right
return node
elif(node.right==None):
node = node.left
return node
elif(node.right and node.left):
delete = node.right
while(delete.left):
delete = delete.left
node.data = delete.data
node.right = delete(node.right,delete.data)
return node
testTree.delete(testTree.root,30)
testTree.printInorder(testTree.root)
我可能不会直接删除吗?
答案 0 :(得分:0)
您已撰写node = node.right
,但您真正想要的是return node.right
(左侧情况也类似)。
因为父母的左或右子项将被设置为返回值,所以不应再有对当前节点的引用,它将被垃圾收集。
同样,当node
没有子节点时,您正在执行del(node)
(顺便说一下括号是不必要的),这只会使node
成为未定义的名称。
您应该执行return None
,以便将父级的左或右子项设置为None
,然后从没有引用的方式对该节点进行垃圾收集。
在要删除的节点有两个子节点的情况下,您正在设置node.data = delete.left
,这可能是将节点分配给应该是整数值的节点。您可能需要node.data = delete.data
。
此外,您可能不想只做del(node.right)
。所有这一切都将从right
中删除属性node
。您应该跟踪delete
的父母,并将其作为该父母的子女删除。
另一个问题是如果delete
有孩子。所有人都说,有很多问题,所以可能是其中任何一个。
编辑:为了解决最新版本的代码,这两个子代案例可能是这样的:
swap_node = node.right
parent = node
# Find the leftmost child of the right subtree and its parent
while swap_node.left:
parent = swap_node
swap_node = swap_node.left
node.data = swap_node.data
# The next line works whether or not swap_node has a right child
parent.left = swap_node.right
return node
这会将数据从右子树的最左边的子节点移动到当前节点,并从其树中删除该节点。您不需要递归调用删除,因为您已经知道节点在哪里并且没有左子节点。