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

二叉搜索树(BST)懒删除实现问题:标记删除后查询仍返回存在

问题

我实现了一个二叉搜索树(BST)类,正在尝试理解「懒删除(lazy deletion)」的工作原理。我为节点设置了removed标记来标识其是否已被删除,当找到要删除的值时会将该标记设为True,但调用findValue方法时,仍会判定已删除的值存在。我查阅了懒删除的相关资料,资料均提到只需设置标记并在找到目标值时设为True,请问我是否还需要实现其他逻辑?或者我遗漏了什么关键步骤?

以下是我的Python代码:

class Node:

    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None
        self.removed = False

    def setLeft(self, left):
        self.left = left

    def setRight(self, right):
        self.right = right

    def getLeft(self):
        return self.left

    def getRight(self):
        return self.right

    def getValue(self):
        return self.value


class Tree:

    def __init__(self):
        self.root = None

    def insertValue(self, value):
        """add a new node containing value to the tree """
        if self.root is None:
            temp = Node(value)
            self.root = temp
            return
        self.recInsertValue(value, self.root)

    def recInsertValue(self, value, ptr):
        if value < ptr.value:
            if ptr.getLeft() is None:
                temp = Node(value)
                ptr.left = temp
            else:
                self.recInsertValue(value, ptr.getLeft())
        else:
            if ptr.right is None:
                temp = Node(value)
                ptr.right = temp
            else:
                self.recInsertValue(value, ptr.right)

    def findValue(self, value):
        """return true if there is a node containing value, false otherwise"""
        ptr = self.root

        while ptr is not None:
            if ptr.value == value:
                return True
            if value < ptr.value:
                ptr = ptr.getLeft()
            else:
                ptr = ptr.getRight()
        return False

    def removeValue(self, value):
        ptr = self.root
        while ptr is not None:
            if ptr.value == value:
                ptr.removed = True
                return True
            if value < ptr.value:
                ptr = ptr.getLeft()
            else:
                ptr = ptr.getRight()
        return False


    def inOrder(self):
        return self.recInOrder(self.root)


    def recInOrder(self, ptr):
        buffer = ""
        if ptr is not None:
            buffer += self.recInOrder(ptr.getLeft())
            buffer += str(ptr.getValue()) + " "
            buffer += self.recInOrder(ptr.getRight())
            return buffer
        return ""
解答

你遗漏了标记检查的核心逻辑——懒删除的本质是标记节点为"已删除",但所有涉及节点存在性判断、数据遍历的操作都需要过滤掉removed=True的节点。具体需要修改以下几个关键地方:

  • 修正findValue方法
    当前方法只要找到值匹配的节点就返回True,完全忽略了removed标记。必须在匹配值的同时,检查节点是否处于未删除状态:

    def findValue(self, value):
        """return true if there is a node containing value, false otherwise"""
        ptr = self.root
    
        while ptr is not None:
            if ptr.value == value:
                # 仅当节点未被删除时,才判定值存在
                return not ptr.removed
            if value < ptr.value:
                ptr = ptr.getLeft()
            else:
                ptr = ptr.getRight()
        return False
    
  • 修正中序遍历方法recInOrder
    遍历操作应该只输出未被删除的节点,否则已标记删除的节点仍会被显示,不符合懒删除的预期:

    def recInOrder(self, ptr):
        buffer = ""
        if ptr is not None:
            buffer += self.recInOrder(ptr.getLeft())
            # 仅添加未被删除的节点值到结果中
            if not ptr.removed:
                buffer += str(ptr.getValue()) + " "
            buffer += self.recInOrder(ptr.getRight())
            return buffer
        return ""
    
  • 可选:处理重复值场景
    如果你的BST允许插入重复值,当前removeValue只会标记第一个匹配的节点。若需要支持删除所有匹配值,或多次删除同一值(比如插入多个相同值后,每次删除标记一个未被删除的节点),需要调整removeValue的逻辑——比如遍历所有匹配节点并标记,或者找到第一个未被删除的匹配节点再标记。

  • 可选:后续清理优化
    懒删除的优势是延迟真正的节点删除操作,当树中被标记删除的节点占比过高时,可以在空闲时机(比如插入新节点时、定期触发)一次性清理这些节点,重新调整树结构,避免查询、遍历性能下降。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:15:40