algorithm - n 个节点可以生成多少个非同构完整二叉树?
问题描述
同构意味着交换自己的完整二叉树的任意子树可以与另一棵相同。
答案肯定不是加泰罗尼亚数,因为加泰罗尼亚数的数量包括同构数。
解决方案
我假设n
节点是指n
内部节点。所以它会有2n+1
顶点和2n
边。
接下来,我们可以对二叉树进行排序,如下所示。具有更多节点的树更大。如果两棵树的节点数相同,则比较左侧,并通过比较右侧来打破平局。如果两棵树按此顺序相等,则通过归纳法不难证明它们是同一棵树。
对于您的问题,我们可以假设对于每个同构类,我们只对该同构类中的最大树感兴趣。请注意,这意味着左子树和右子树在它们的同构类中也必须是最大的,并且左子树必须与右子树相同或大于右子树。
所以假设这是具有节点f(n)
的非同构二叉树的数量。n
我们现在可以递归了。以下是我们的案例:
n=0
有一棵,空树。n=1
有一个。一个有 2 片叶子的节点。n > 1
. 让我们迭代m
,右边的数字。如果然后在右边,左边2m+1 < n
有最大的树,所有这些都是最大的。如果我们想要一个在右边有节点的最大树,在左边有一个有节点的最大树,右边的树必须小于或等于左边的树。但是有一个众所周知的公式可以说明有多少种方法可以做到这一点,那就是. 最后我们不能有,因为在那种情况下我们没有最大的树。f(m)
f(n-m-1)
f(m) * f(n-m-1)
2m+1 = n
m
m
f(m) * (f(m) + 1) / 2
n < 2m+1
使用它,您应该能够编写一个递归函数来计算答案。
更新这是一个这样的功能:
cache = {0: 1, 1:1}
def count_nonisomorphic_full_trees (n):
if n not in cache:
answer = 0
for m in range(n):
c = count_nonisomorphic_full_trees(m)
if n < m+m+1:
break
elif n == m+m+1:
answer = answer + c*(c+1)//2
else:
d = count_nonisomorphic_full_trees(n-m-1)
answer = answer + c*d
cache[n] = answer
return cache[n]
请注意,它开始时比加泰罗尼亚数字慢,但仍呈指数增长。
推荐阅读
- tcp - webRTC 应用程序多久需要一次 TURN 服务器
- java - 使用 Spring Boot 将自定义 Http 标头添加到 SOAP 请求
- java - 从类到活动的数据传递问题
- android - 自定义 pathPattern 的意图过滤器
- c# - 如何检查给定对象是否为空/空可枚举?
- java - 如何使特定索引的按钮播放声音
- c++ - ReadProcessMemory 失败,错误代码为 299 (ERROR_PARTIAL_COPY)
- sql - 数组中的至少一个元素存在于另一个数组中
- arrays - 使用c将结构数据数组追加和删除到文件中
- azure-data-factory-2 - azure 数据流中是否有办法按多个类别取消数据透视?