You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python BST节点删除函数异常:误删多节点及重复附加问题排查

BST节点删除逻辑错误排查

问题现象

  • 删除值45时,误删了45、30、20三个节点
  • 删除值40时,未删除目标节点40,反而删除了40之后的所有节点,并重复附加30、20、45节点

问题定位

调试发现以下代码段是删除45时误删20和30的直接原因:

if node.right is None and node.left is None:
    pn.right = None
    pn.left = None

相关函数实现

删除根节点函数 remove_start_node

def remove_start_node(self) -> bool:
    """
    删除BST的根节点。首先检查BST是否为空,或者是否只有根节点存在。
    如果为空,返回False;如果只有根节点,直接删除根节点;
    否则,找到根节点的中序后继(右子树的最左子节点)。
    如果被删除的节点只有左子树,左节点成为子树的根节点。
    """
    if self._root is None:
        return False
    if self._root.left is None and self._root.right is None:
        self._root = None
    elif self._root.right is None:  # 检查是否只有左子树存在
        self._root = self._root.left
    else:
        subtree = self._root.right
        par_tree = subtree
        while subtree.left is not None:  # 遍历找到中序后继(最左子节点)
            par_tree = subtree
            subtree = subtree.left
        if subtree != self._root.right:  # 重建树结构
            par_tree.left = subtree.right
            subtree.right = self._root.right
        subtree.left = self._root.left
        self._root = subtree
    return True

删除普通节点函数 remove

def remove(self, value) -> bool:
    """
    遍历BST并删除目标值,同时重建BST结构。
    首先检查BST是否为空、是否只有一个节点,以及值是否存在于BST中。
    如果为空,返回False;如果只有一个节点,删除根节点;否则,找到当前节点的中序后继(当前节点右子树的最左子节点)。
    如果被删除的节点只有左子树,当前节点成为左子树的根节点。
    """
    if not self.contains(value):  # 检查值是否存在
        return False
    if self._root is None:  # 检查BST是否为空
        return False
    if self._root.value == value:  # 检查值是否匹配根节点
        self.remove_start_node()
        return True

    # 遍历树直到找到目标值
    x = self._root
    pn = None
    while x is not None:  # 遍历树
        if x.value == value:
            node = x
            break
        elif value < x.value:
            pn = x
            x = x.left
        else:
            pn = x
            x = x.right

    # 如果后继节点没有子节点,将父节点的子节点设为None
    if node.right is None and node.left is None:
        pn.right = None
        pn.left = None
    elif node.right is None:  # 如果后继节点只有左子节点,将父节点指向其子节点
        pn.right = node.left
    else:  # 找到后继节点后,遍历到最左子节点
        subtree = node.right
        par_tree = subtree
        while subtree.left is not None:
            par_tree = subtree
            subtree = subtree.left
        if subtree != node.right:  # 重建树结构
            par_tree.left = subtree.right
            subtree.right = node.right
        pn.right = subtree  # 将父节点指向新的子树
        temp = node.left  # 保存被删除节点的其他子树
        node = subtree  # 用后继节点替换当前节点
        node.left = temp  # 重新附加剩余子树
    return True

测试案例

-------------------------------
输入  : BST前序遍历 { 1, 2, 3 } 删除: 1
结果 : BST前序遍历 { 2, 3 }
输入  : BST前序遍历 { 1, 2, 3 } 删除: 2
结果 : BST前序遍历 { 1, 3 }
输入  : BST前序遍历 { 1, 2, 3 } 删除: 3
结果 : BST前序遍历 { 1, 2 }
输入  : BST前序遍历 { 50, 40, 30, 20, 45, 60, 70, 80 } 删除: 0
结果 : BST前序遍历 { 50, 40, 30, 20, 45, 60, 70, 80 }
**输入  : BST前序遍历 { 50, 40, 30, 20, 45, 60, 70, 80 } 删除: 45
结果 : BST前序遍历 { 50, 40, 60, 70, 80 }
输入  : BST前序遍历 { 50, 40, 30, 20, 45, 60, 70, 80 } 删除: 40
结果 : BST前序遍历 { 50, 40, 30, 20, 45, 30, 20, 45, 30, 20 }**
输入  : BST前序遍历 { 50, 40, 30, 20, 45, 60, 70, 80 } 删除: 30
结果 : BST前序遍历 { 50, 40, 30, 20, 20, 60, 70, 80 }

疑问

请问我在节点重连的逻辑中哪里出错了?

内容的提问来源于stack exchange,提问作者310ToPoona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 18:25:39