在O(1)中的bst中查找继任者和前任者

时间:2020-06-07 13:31:45

标签: algorithm data-structures binary-search-tree

有没有一种方法可以在插入或删除节点时将一些信息添加到节点中。这样就有可能获得O(1)中的后继者和前任者。

1 个答案:

答案 0 :(得分:2)

如果在每个节点中还存储了对父节点的引用,那么可以看到在给定节点的情况下如何找到下一个节点:

getNext(node):
    if node.right is not null:
        node = node.right
        while node.left is not null:
            node = node.left
        return node
    while node.parent is not null:
        if node.parent.left == node:  # node is a left child
            return node.parent
        node = node.parent  # node was a right child
    # no more nodes...
    return null

如您所见,其中涉及到循环,因此这需要花费不同的时间。在最坏的情况下,跟随叶的节点可能是根,而跟随根的节点可能是深叶。因此,一次调用最多可能涉及到node h 个重新分配,之后是树中的许多边缘( h 是树的高度)。

但是,如果您考虑从最左边的叶子开始在所有节点上进行完整遍历,则会看到每个边沿都精确地遍历了2次:第一次使用leftright,第二次与parent。除了从根到最左边的叶子的路径上的边缘以外,这些边缘仅用parent访问一次。但是为了简单起见,我们只说他们也被访问过两次(我们对工作进行了高估)。

这意味着对于对getNext n 调用(先前的结果将馈入下一个调用,而最后一个调用返回null),您将访问< em> 2(n-1)边缘,这意味着平均一个呼叫遍历 2(n-1)/ n 边缘,该边缘总是(略小于)2。 >

因此,这表示摊销后的 O(1)时间复杂度。

当然,getPrevious的算法将是相似的,并且具有相同的时间复杂度注意事项。

可以轻松扩展用于插入和删除操作(包括自平衡树中的旋转)的算法,以在不增加时间复杂度的情况下也更新每个相关节点中的parent参考。

相关问题