在BST中删除

时间:2018-05-29 21:25:57

标签: python binary-search-tree

我想知道为什么我的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)

我可能不会直接删除吗?

1 个答案:

答案 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

这会将数据从右子树的最左边的子节点移动到当前节点,并从其树中删除该节点。您不需要递归调用删除,因为您已经知道节点在哪里并且没有左子节点。