在O(1)中找到BinaryTree中的前驱

时间:2018-05-01 11:18:19

标签: time-complexity binary-tree

我对以下问题遇到了麻烦

我有一个给定的二叉树(不一定是BST)和两个指针(x,y),我需要找到X是Y的前导,在O(1)复杂度中,我可以添加尽可能多的字段我想要的。

当我将下一个子项插入到树中时,我正在考虑将每个前任作为字段添加,但是这样我如何搜索X是否是Y(1)复杂度中的前任。

1 个答案:

答案 0 :(得分:0)

如果你使用节点,添加一个unsigned int字段,称之为L,从root开始为1。

当您递归插入时,取上一个节点的值并乘以2然后如果向右移动则加1,或者如果向左移动则简单地乘以2。

您将获得一个L值的树,如下所示:

          1
         / \
        /   \ 
       /     \
      /       \
     10       11 
    /  \      / \
   /    \    /   \
 100   101 110   111
  \             /  \
 1001         1110  1111
   /
10010

祖先P的值应为P.LP.LC.L的子字符串,P.L中的位数严格小于C.L L中的位。

base-10中树的 1 / \ / \ / \ / \ 2 3 / \ / \ / \ / \ 4 5 6 7 \ / \ 9 14 15 / 18 值为:

log_2(L)

如果您有两个指针,如果您选择L,您将获得该数字// Parent (ancestor) has equal or more bits? if (log(P.L) >= log(C.L)) { // parent is not an ancestor because it // is either lower in tree, or at same level } 中的位数,如果您注意到,则表示您所在树中的级别。< / p>

所以如果:

bits(P)

如果该检查通过,则从bits(C)减去C,这将告诉您C.L比P.L多多少位。或者,P的级别低于int D = log(C.L) - log(P.L)

C

由于C.L较低,我们所做的所有计算L值都是乘法父项&#39}。 D值乘以2(向左移位)一定次数,如果我们将C向右移(向前移2)D次,则第一个// Divide by 2, D times int c = C.L >> D // Is P.L a substring of C.L? if (c == P.L) { // P.L is a substring of C.L // means P is an ancestor of C } // If we get here, C is below P in the tree, but C // is not in a subtree of P because the first `D bits don't match` 位应该匹配。

C.L

本质上,我们使用整数作为字符串来跟踪插入的路径,并且我们使用位操作来检查P.L是否是P.L在恒定时间内的子字符串。

注意,如果您使用了数组,则C.L和{{1}}只是您要检查的节点的索引。