我在many different languages中看到了很多不同的BK树实现,而且它们似乎都没有包含从树中删除节点的方法。
即使the original article where BK Trees were first introduced也未提供有关节点删除的有意义的见解,因为作者仅建议将节点标记为已删除,以便忽略该节点:
结构1 [BK树]和2中的键的删除遵循类似于上述的过程,特别考虑要删除的键是代表性的x°[根键]的情况。在这种情况下,不能简单地删除密钥,因为它对于结构信息是必不可少的。相反,必须为每个键使用额外的位,表示该键是否实际上对应于记录。相应地修改搜索算法以忽略与记录不对应的密钥。这涉及在Update过程中测试额外的位。
虽然理论上可以正确删除BK树中的节点,但是可以在线性/次线性时间内这样做吗?
答案 0 :(得分:1)
虽然理论上可以正确删除 BK 树中的节点,但是否可以在线性/次线性时间内这样做?
如果您想从 BK 树中物理删除它,那么我想不出一种方法可以在所有情况下在线性时间内完成此操作。考虑删除节点时的 2
场景。请注意,我没有考虑与计算 Levenshtein 距离相关的时间复杂度,因为该操作不依赖于单词的数量,尽管它也需要一些处理时间。
在这里,即使步骤 1
可以在 O(1) 中完成,步骤 2
和 4
的成本要高得多。插入单个节点是 O(h),其中 h 是树的高度。更糟糕的是,必须对原始节点的每个子节点都这样做,因此它将是 O(k*h),其中 k 是子节点的数量。
重建一棵树在最好的情况下至少需要 O(n),否则为 O(h*n)。
这就是为什么最好不要物理删除节点,而是将其保留在树中并将其标记为deleted
。这样,它将像以前一样用于插入新节点,但会从拼写错误的单词的建议结果中排除。这可以在 O(1) 内完成。