是的,我不得不说这是某种功课,我不希望得到答案,但我不知道如何继续这里。
我知道如何以多种方式找出继任者和前任,但没有一个人能及时完成O(1)。
练习说我们可以在每个节点上节省更多的信息。但是,插入和删除功能应该是恒定的O(h),其中h是树的高度。
我的第一个也很容易实现的想法是在每个节点中保存这个节点有多少个左和右节点。因此,每次传递节点时,我都必须更改插入和删除方法,以便为每个节点增加或减少这些变量。但我不知道这些信息如何能够超越O(1)的时间复杂度。
答案 0 :(得分:2)
如果您需要能够在O(1)时间内找到前导者和后继者,那么除了将节点链接到BST之外,您还可以将节点链接到双向链接列表中。
这并不会改变插入操作的复杂性,因为在正常插入过程中您将找到新节点的后继和前任。你只需记住它们就可以在将所有内容链接在一起时使用它们。
请注意,即使没有额外的链接(假设您有父链接),找到节点的后继或前任也需要平均,即使它需要O(log N)时间在最坏的情况下。因此,在实践中通常不会使用与后继者和前任者的额外链接。
答案 1 :(得分:1)
这对我来说似乎是一个有缺陷的练习。从根遍历所需的密钥需要花费O(h)时间,因此找到密钥后继的解决方案需要O(h)+时间才能找到后继。
忽略这个事实,比如你是否神奇地在所需的关键节点,你可以实现O(1)时间的唯一方法是预先存储所有节点的后继者和前任者。插入和删除线索是这样的,即每次插入节点或从树中删除时,您都需要重新计算所有节点的后继和前任。
更新:正如Yves在评论中指出的那样,后续版只会针对某个节点进行更新
答案 2 :(得分:1)
是的!可以做到。但是使用O(n)额外的空间。
遍历树并将后继信息存储到map (or hashmap)
。其中key
将是当前节点的值,value
将是后继节点的值。这将使用O(n)
空格,但回答查询的时间复杂度始终为O(1)
。