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

Posted

技术标签:

【中文标题】查找完全二叉树的不相关分区【英文标题】:Find unrelated partitions of a complete binary tree 【发布时间】:2021-12-03 04:04:02 【问题描述】:

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

注意: 不相关的分区意味着其直接父级不能存在子级。

每个分区的节点数有限制。 一个分区的最大节点数与该分区的最小节点数之差可以是0也可以是1。

此外,root 被排除在分区之外。

【问题讨论】:

什么是h 用于具有 7 个节点的完整树? @WalterTross h 对于具有 7 个节点的完整二叉树来说是 2。考虑根节点在h = 0 为什么这个标签同时带有 java 和 python 的标签? 无论如何,如果分区是指一组节点,不受其数量的限制,那么通过让根与叶子属于同一分区,可以轻松满足不相关分区的条件,并且中间的每一层都属于不同的分区 @WalterTross Final 这是。保证不再更改。 【参考方案1】:

谁设计了这个问题可能有一个更优雅的解决方案,但以下工作。

假设我们有编号为1hh 分区,并且分区n 的节点具有值n。根节点的值为0,不参与分区。即使n 为偶数,我们也称其为分区,如果n 为奇数,我们也称其为奇数。让我们也对完整二叉树的级别进行编号,忽略根并从级别 1 开始,有 2 个节点。级别n有2n个节点,完整的树有2h+1-1个节点,但只有P=2h+1-2 个节点属于分区(因为不包括根)。每个分区由p=⌊P/h⌋或p=⌈P/h⌉节点组成,使得∑ᵢpᵢ=P。

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

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

这是 h 最多 7 个的结果(为此,我以紧凑的方式在终端上写了一个很小的 ​​Python library to print binary trees):

 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 的树都已通过程序确认符合规范。

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

【讨论】:

以上是关于查找完全二叉树的不相关分区的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的相关操作

PHP数据结构-完全二叉树线索二叉树及树的顺序存储结构

PHP数据结构-完全二叉树线索二叉树及树的顺序存储结构

每日一道面试题-完全二叉树的判断

树二叉树满二叉树完全二叉树遍历二叉树java实现

算法总结:左神—利用二分查找思想:完全二叉树节点数,求一个整数k的N次方