枚举和索引n个顶点的所有可能树

时间:2017-03-13 02:34:14

标签: c++ algorithm indexing tree

我们一直在尝试找到一种方法来枚举和索引所有可能具有n个标记顶点的树。根据Cayley定理, n 标记顶点的树的 n n -2 数量。在C / C ++中,有没有办法索引所有可能的树,这样当用户输入整数/数字时,会实时生成一个唯一的树?

2 个答案:

答案 0 :(得分:1)

快速浏览维基百科关于Cayley's formula的文章(你提到的 n n -2 公式)向我指出Prüfer序列,是由(可能重复的)节点标签组成的长度 n -2的序列。很明显, n n -2 这样的序列,每个序列都可以表示为 n - 2位数字 n 号码。不太明显的是,每个Prüfer序列对应一个带有 n 标记节点的唯一树,但这个事实足以证明Cayley的公式。

关于Prüfer序列的维基百科文章解释了如何转向a sequence into its corresponding tree;这相当于将整数转换为树。

我没有尝试过这些,但它看起来很有说服力。

答案 1 :(得分:0)

我不熟悉C或C ++,但我认为我可以提供这样的理论,即列举每棵树都不应该太难。评论我是否需要澄清任何内容。

想想二元。

采用邻接矩阵。为了描述一个顶点是否连接到另一个顶点,我们使用1或0.因此,为了使用邻接矩阵找到所有图形,我们将填充具有1和0的所有组合的矩阵。唯一的约束是对于树,a节点不能是自己的父节点,也不能有多个父节点。有三个顶点的示例:

0 1 1  0 1 1  0 0 1
1 0 0  0 0 0  1 0 0
0 0 0  1 0 0  0 1 0 etc.

我们可以做的是将行并排放置,使得二进制序列描述每个矩阵。例如:

0 1 1 1 0 0 0 0 0  0 1 1 0 0 0 1 0 0  0 0 1 1 0 0 0 1 0 etc.

因此,给定9位,我们可以描述具有三个顶点的所有图形。这转化为每个数字1-2 ^ 9的一棵树,减去彼此旋转的数字。

要将数字转换为树,只需将数字转换为二进制,然后将二进制数转换为矩阵。为每个" 1"修复自我连接。在对角线上或越过对角线,将其进一步移动。那么:

1 0 0         1 0 1 
0 1 0    ->   0 0 0
0 0 1         0 1 0