我对以下问题遇到了麻烦
我有一个给定的二叉树(不一定是BST)和两个指针(x,y)
,我需要找到X是Y的前导,在O(1)复杂度中,我可以添加尽可能多的字段我想要的。
当我将下一个子项插入到树中时,我正在考虑将每个前任作为字段添加,但是这样我如何搜索X是否是Y(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.L
,P.L
是C.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}}只是您要检查的节点的索引。