如何区分左子树或右子树中的元素

时间:2018-12-21 19:15:56

标签: algorithm math

假设我们有一个像这样的树结构:

example tree

这由15个节点组成,可以大于或小于此节点。但是顺序是精确的,树给节点从左到右,从上到下的顺序号。

问题是:如何区分节点在左子树(2-4-5-8-9-10-。)还是右子树(3-6-7-12- ...)。

我期望的是,找到一个数学公式或编码算法,向我显示子节点所在的子树。只有输入/值是元素的订单号。

2 个答案:

答案 0 :(得分:1)

假设您的电话号码为N。

您可以通过R = floor(log 2 (N))(从0开始)来找到N行。

该行的第一个和最后一个数字分别是2 R 和2 R + 1 -1。因此,您只需要找出N靠近哪个端点即可。

具体来说,N在左侧子树iff中:

N-2 R <2 R + 1 -1-N

重新排列和替换:

N <(3 * 2 floor(log 2 (N))-1)/ 2


使用Python 3进行完整性检查(True表示左侧子树; False表示右侧):

>>> from math import floor, log2
>>> for N in range(1,16):
...     print(N, N < (3*2**floor(log2(N)) - 1)/2)
...
1 False
2 True
3 False
4 True
5 True
6 False
7 False
8 True
9 True
10 True
11 True
12 False
13 False
14 False
15 False

答案 1 :(得分:1)

@arshajii的答案起作用了,尽管我认为1不应被视为在左子树中。使用标准数学函数,该答案也是一个很好的“数学公式”。但是,对于仅涉及整数的问题,该答案使用浮点运算。这是解决问题的另一种方法。

如果您查看树中数字的二进制展开,您将看到左子树中的数字在第二高有效位中有一个0位,而在树中的数字右子树在第二个最高有效位中具有一个1位。检查该位是容易且快速的,尽管在不同的编程语言中,如何执行的操作也有所不同。

以下是在Python 3中执行此操作的两种方法:

not (n & (1 << n.bit_length() - 2))

bin(n)[3]=='0'

要检查正确的子树,请从第一种方法中删除not或在第二种方法中将0更改为1

在我的系统上,@ arshajii的答案需要1.34毫秒才能工作(使用%timeit检查)。我的第一种方法需要260微秒,而第二种方法则需要257微秒。因此,我的任何一种方法都比@arshajii的代码快五倍以上。对我的代码进行类似的检查是

for n in range(2,16):
    print(bin(n)[3]== '0')

和产量

True
False
True
True
False
False
True
True
True
True
False
False
False
False