查找完全二叉树的不相关分区



我有一个高度为'h'的完整二叉树。
我如何找到'h'个不相关的分区?

注意:不相关分区意味着没有子分区可以与其直接父分区同时存在。

对每个分区中的节点数量有一个约束。分区中最大节点数与最小节点数之差可以为0或1。

同时,根目录被排除在分区之外。

设计这个问题的人可能有一个更优雅的解决方案,但下面的方法是可行的。

假设我们有编号为1hh分区,并且分区n的节点值为n。根节点的值为0,不参与分区。如果n是偶数,我们称其为偶数;如果n是奇数,我们称其为奇数。让我们还为完整二叉树的级别编号,忽略根,从具有2个节点的1级别开始。级别n有2n节点,完整树有2h+1-1节点,但只有P=2h+1-2节点属于分区(因为根被排除在外)。每个分区由p=⌊p/h⌋或p=≤p/h²节点组成,使得∑∑∑p∑p= p

如果树的高度h为偶数,则将所有偶数分区放入左子树的偶数层和右子树的奇数层,将所有奇数分区放入左子树的奇数层和右子树的偶数层。

如果h为奇数,则像偶数情况一样,将所有分区分布到h-1分区,而将h分区均匀分布到左、右子树的最后一层。

这是h到7的结果(为此目的,我编写了一个很小的Python库,以紧凑的方式将二叉树打印到终端):

0
1 1
0
1   2
2 2 1 1
0
1       2
2   2   1   1
1 1 3 3 2 2 3 3
0
1               2
2       2       1       1
1   1   1   1   2   2   2   2
2 4 4 4 4 4 4 4 1 3 3 3 3 3 3 3
0
1                               2
2               2               1               1
1       1       1       1       2       2       2       2
2   2   2   2   2   2   4   4   1   1   1   1   1   1   3   3
3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5
0
1                                                               2
2                               2                               1                               1
1               1               1               1               2               2               2               2
2       2       2       2       2       2       2       2       1       1       1       1       1       1       1       1
1   1   1   1   1   1   3   3   3   3   3   3   3   3   3   3   2   2   2   2   2   2   4   4   4   4   4   4   4   4   4   4
4 4 4 4 4 4 4 4 4 4 4 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
                                                         0
1                                                                                                                               2
2                                                               2                                                               1                                                               1
1                               1                               1                               1                               2                               2                               2                               2
2               2               2               2               2               2               2               2               1               1               1               1               1               1               1               1
1       1       1       1       1       1       1       1       1       1       1       1       1       1       1       1       2       2       2       2       2       2       2       2       2       2       2       2       2       2       2       2
2   2   2   2   2   2   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   4   1   1   1   1   1   1   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 4 4 4 4 4 4 4 4 4 4 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7

生成它的代码是:

from basicbintree import Node
for h in range(1, 7 + 1):
root = Node(0)
P = 2 ** (h + 1) - 2  # nodes in partitions
p = P // h  # partition size (may be p or p + 1)
if h & 1:  # odd height
t = (p + 1) // 2  # subtree tail nodes from split partition
n = (h - 1) // 2  # odd or even partitions in subtrees except tail
else:  # even height
t = 0  # no subtree tail nodes from split partition
n = h // 2  # odd or even partitions in subtrees
s = P // 2 - t  # subtree nodes excluding tail
r = s - n * p  # partitions of size p + 1 in subtrees
x = [p + 1] * r + [p] * (n - r)  # nodes indexed by subtree partition - 1
odd  = [1 + 2 * i for i, c in enumerate(x) for _ in range(c)] + [h] * t
even = [2 + 2 * i for i, c in enumerate(x) for _ in range(c)] + [h] * t
for g in range(1, h + 1):
start = 2 ** (g - 1) - 1
stop = 2 ** g - 1
if g & 1:  # odd level
root.set_level(odd[start:stop] + even[start:stop])
else:  # even level
root.set_level(even[start:stop] + odd[start:stop])
print('```none')
root.print_tree()
print('```')

所有高度27以下的树木都已通过程序确认符合规格。

算法的某些部分需要证明,例如,在奇数高度的情况下,总是可以为分割分区选择偶数大小,但这和其他证明留给读者作为练习;-)

相关内容

  • 没有找到相关文章

最新更新