计数二叉树


28

(我是一名具有一定数学背景的学生,我想知道如何计算特定种类的二叉树的数量。)

综观对维基百科页面二叉树的,我已经注意到了这个说法,即大小的扎根二叉树的数量应该是这样的加泰罗尼亚号码C_N = \ dfrac {1} {N + 1} {2N \选择N}n

Cn=1n+1(2nn)

但是我不明白我自己怎么能得出这样的结果?有找到这种结果的方法吗?

现在,如果不考虑子树的顺序(左,右)?例如,从我的角度来看,我认为这两棵树是相同的:

   /\   /\
  /\     /\

是否可以应用类似的方法来计算这些对象中有多少个恰好具有n节点?


Polya的基于二叉树的计数定理在这里适用吗?
Nicholas Mancuso 2012年

Answers:


35

为了对多种类型的组合对象(如本例中的树木)进行计数,有强大的数学工具(符号方法)使您可以从描述中机械地推导此类组合对象的构造方式。这涉及生成函数。

已故的Philipe Flajolet和Robert Sedgewick的《分析组合》是一个很好的参考。可从上面的链接获得。

已故的赫伯特·威尔夫(Herbert Wilf)的著作《生成功能论》是另一本免费资料。

当然,GKP的具体数学是宝库。


对于二叉树,它是这样的:首先,您需要对树进行清晰的定义。

二叉树是一个根树,其中每个非叶节点的度数均为2。

接下来,我们必须同意我们所谓的大小

在此处输入图片说明

在左侧,所有节点均相等。在中间,我们区分叶子和非叶子。在右侧,我们有一棵修剪过的二叉树,其中的叶子已被去除。请注意,它具有两种类型的一元分支(左和右)!

现在我们必须对这些组合对象的构建方式进行描述。在二叉树的情况下,递归分解是可能的。

令为第一类型的所有二叉树的集合,然后象征性地得到: A在此处输入图片说明

它的内容为:“二叉树类的对象是一个节点或一个节点,后跟两个二叉树。”这可以写成集合方程:

A={}({}×A×A)

通过引入枚举此类组合对象的生成函数,我们可以将设置的方程式转换为涉及生成函数的方程式。A(z)

A(z)=z+zA2(z)

我们选择均等对待所有节点并将树中的节点数作为其大小的概念的选择是通过用变量标记节点来表示的。z

我们现在可以解决二次方程为和得到,像往常一样,两种溶液中,生成函数的明确的闭合形式:zA2(z)A(z)+z=0A(z)

A(z)=1±14z22z

现在我们只需要牛顿(广义)二项式定理:

(1+x)a=k=0(ak)xk

其中和可将生成函数的闭合形式扩展回幂级数。我们这样做是因为,处的系数只是大小为的组合对象的数量,通常写为。但是在这里,我们关于树的“大小”的概念迫使我们在处寻找系数。经过与二项式和阶乘的杂耍,我们得到:a=1/2x=4z2znn[zn]A(z)z2n+1

[z2n+1]A(z)=1n+1(2nn).

如果我们从大小的第二个概念开始,则递归分解为:

在此处输入图片说明

我们得到了另一类组合对象。它写道:“二叉树类的对象是叶子或内部节点,后跟两个二叉树。”B

我们可以使用相同的方法,并将转换为。只是这一次变量仅标记内部节点,而不标记叶子,因为此处的“大小”定义不同。我们也得到了一个不同的生成函数:B={}({}×B×B)B=1+zB2(z)z

B(z)=114z2z

提取系数产量

[zn]B(z)=1n+1(2nn).

类和同意的计数,因为与二进制树内部节点具有叶,因此中总节点。ABnn+12n+1

在最后一种情况下,我们必须更加努力:

在此处输入图片说明

这是对非空修剪二进制尝试的描述。我们将此扩展到

C={}({}×C)({}×C)({}×C×C)D={ϵ}({}×C×C)

并用生成函数重写

C(z)=z+2zC(z)+zC2(z)D(z)=1+zC2(z)

求解二次方程

C(z)=12z14z2zD(z)=114z2z

再来一次

[zn]C(z)=1n+1(2nn)n1[zn]D(z)=1n+1(2nn)n0

请注意,加泰罗尼亚语生成函数

E(z)=114z2

它列举了普通树木的类别。那是对节点度没有限制的树。

E={}×SEQ(E)

它的内容为:“一般树类的对象是一个节点,后面跟着可能是空的一般树序列。”

E(z)=z1E(z)

利用拉格朗日-伯曼反演公式,我们得到

[zn]E(z)=1n+1(2nn)

因此,我们证明了普通树和二叉树一样多。难怪在通用树和二叉树之间存在双射。双射被称为旋转对应关系(在链接文章的末尾进行了说明),它使我们可以将每个普通树作为二叉树存储。

请注意,如果我们不区分类中的左右同级,则会得到另一类的树:CT

在此处输入图片说明

一元二叉树。 它们也具有生成函数 但是它们的系数不同。您得到的Motzkin数

T={}×SEQ2(T)
T(z)=1z12z3z22z
[zn]T(z)=1nk(nk)(nkk1).

哦,如果您不喜欢生成函数,那么还有很多其他证明。看到这里,您可以在其中使用二叉树的编码作为Dyck单词,并从其递归定义中得出递归。然后解决该复发问题也将给出答案。但是,由于符号方法直接与组合对象的蓝图一起使用,因此可以避免您一开始就遇到重复问题。


只是要注意,Sedgewick和Flajolet的“算法分析简介”(aofa.cs.princeton.edu)与“ Analytic Combinatorics”一书涵盖了许多相同的材料,但是形式更易于访问。
vonbrand 2013年

7

生成函数是一个非常强大且非常有用的魔术棒。对于第一个问题(为什么有树)的以下解决方案却没有那么神奇。因此,可爱。Cn

例。为了产生一个由节点组成的树,我们从一个序列开始,其中发生次,而发生次。例如,。在总和最小(且可能为负)的前缀中,选择最长的前缀;在这种情况下,。从头开始使用此前缀,并在末尾添加;在这种情况下,我们得到。现在将变成,将变成;在这种情况下,我们得到。从开头删除,然后添加5+15+115+++++++++++++++++TETTETETTETEETE在最后; 在这种情况下,我们得到TETETTETEEE。这是对树的描述T(E,T(E,T(T(E,T(E,E)),E)))。下面是为什么这是双射的一些解释。一旦您确信了这一点,计数就很容易了。有序列,然后我们除以因为我们选择了可能的循环置换之一。(5+65)±15+6

第一次双射。机器学习中树的典型定义是type tree = T of tree * tree | E; 也就是说,一棵树要么具有两个(有序)子树,要么为空。这是树木的构造方法:T(T(E,E),T(T(E,E),T(E,E)))。丢下绒毛,我们可以简单地写TTEETTEETEE。所有这些描述都将以结尾E,因此是多余的:TTEETTEETE。(请注意,空树现在对应于空字符串。)这些字符串具有以下属性:每个前缀至少具有与Es一样多的T,并且它们总共具有 Ts和 Es,其中是的节点数。那个树。nnn

第二个双射。现在,我们用+1替换T,用-1替换E。因此,我们正在查看具有值+ 1,值-1以及所有前缀的和的。nn0

第三双射。现在,我们稍微更改对前缀的要求:我们要求每个非空前缀的总和。为了使这成为可能,我们让值+1和值-1。(否则,整个字符串的总和将为0,并且不符合前缀的条件。)这些序列必须以+1开头。因此,它们的确与以前相同,只是它们的开头加了+1。>0n+1n

阮内财产。现在暂时忘记序列,并考虑一些整数 ,的有限序列,它们的总和为1。如果所有非空前缀都具有正和,那么此序列的循环置换都不会具有相同的属性。为什么?好吧,假设存在一个,使得也具有所有非空前缀正数。然后(从开始的序列属性)和(从开始的序列属性);因此,x1xmk1xk,,xm,x1,,xk1x1++xk11x1xk++xm1xkx1++xm2,这与整个序列之和为1的假设相矛盾。

而且,给定一些具有和1的序列,总会有一个循环排列,使所有非空前缀都具有正和。(即使是实数也是如此。)

结论。现在,让我们计算与树双射的+1和-1序列。在数字中,我们必须选择等于+1的,其他的将是-1。有种方法。但是,只有在序列计数迄今具有正前缀。因此,有根,有序二叉树的数量为:2n+1n+1(2n+1n+1)12n+1

12n+1(2n+1n+1)=12n+12n+1n+1(2nn)=1n+1(2nn)

很好的答案,但是下面的语句需要一些解释:“给定一些具有和1的序列,总是有一个循环排列,使所有非空前缀都具有正和”。很好
vog 2015年

1
@vog:取总和最小的前缀,并将其移到末尾。
rgrig

1
@vog:如果有多个具有相同的最小和,则它也应该是最长的前缀。我编辑了答案,在开头添加了一个示例。
rgrig
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.