【问题标题】:How to find number of possible binary tree topological permutations?如何找到可能的二叉树拓扑排列的数量?
【发布时间】:2017-02-01 21:40:24
【问题描述】:

给定二叉树节点数 (X) 写入方法,返回具有 X 节点的二叉树的随机排列数。

示例:

X=1: 1

     o

X=2: 2

     o    o
   o        o

X=3: 5

        o    o          o     o        o
      o        o      o         o    o   o
    o            o      o     o

我最终得到了:

    public static int numOfPerms(int numOfNodes) {
       if (numOfNodes<=2 && numOfNodes > 0) {
           return numOfNodes;
       }
       int res = 1;
       for (int i=1; i<=numOfNodes; i++) {
           res = res*(4*i-1)/(i+1);
       }
       return res;
    } 

我希望在这里分享更好的解决方案。

【问题讨论】:

  • 你说的是“排列”,但是树中每个节点的位置重要吗?
  • @Colin D,确实如此 - 它是概率分布
  • 所以节点被编号,例如对于 x=2 我们有两个简单的树:1->2, 2->1?
  • @Alexey 我认为他只是指拓扑,节点本身是相同的(如本示例所示)。并且左右节点的拓扑结构不同。

标签: java algorithm tree binary-tree catalan


【解决方案1】:

我认为Catalan Numbers 可以数你的树(参见关于applications in combinatorics 的部分)。它们形成了一个众所周知的序列,通常由这种递归关系定义:

这种递归经常出现在关于树或递归结构的枚举问题中,因此它被很好地研究了。我链接的维基百科条目为第 n 个加泰罗尼亚数字提供了许多有用的封闭式表达式,即

它们都适合代码实现,并且比任何递归方法都快很多。

【讨论】:

  • 是的,catalan numbers 匹配我自己的递归:f(0)=1; f(x)=sum(f(y)*f(x-y-1), y=0..(x-1))
  • 您应该发布一些有关加泰罗尼亚语数字的实际信息并为他们发布论坛。根据常见问题解答,仅链接的答案是不受欢迎的。
【解决方案2】:

好的,据我所知,您的解决方案不正确,对吧? (对于numOfNodes=4,它返回 12 而不是 14)

直觉上,我会选择递归方法。

  1. 用完一个节点作为父节点
  2. 对于所有可能的分成两组,递归调用这两组的函数
  3. 将每个分区的两组结果相乘,并将所有分区的乘积相加
  4. 返回总和

但在实施之前,我会确保没有简单的公式。我没有快速找到一个(这并不意味着没有)。

编辑:正如另一个答案中所述:您也可以只计算第 n 个加泰罗尼亚数。

【讨论】:

  • Online Encyclopedia of Integer Sequences 在尝试将序列转换为公式时始终是一个很好的起点。
  • 你能帮我弄清楚为什么numOfNodes=4的答案应该是14而不是12吗?我这样计算:8 从最低的叶子(假设它们位于树的第 4 级)到根(第 1 级)+4 从第 3 级的叶子到第 2 级的叶子的方式。我不计算从 lvl 2 到 lvl 3 的方式,因为它们与从 lvl 3 到 lvl 2 的方式相同。所以它给了我 12 ......我错过了什么?
  • @Pshemo in this PDF 由上面的 Colin D 链接,您可以在第 6 页找到 4 个节点的所有排列。
  • 谢谢。现在我知道我计算错了,而不是我应该的:)
  • @Pshemo 是的,你错过了 3 级有两片叶子的树(其中有两棵树)
【解决方案3】:

试试这个递归方法:

static int numOfPerms(int numOfNodes) {
    if (numOfNodes == 1) {
        return 1; 
    }

    numOfNodes = numOfNodes - 1;
    return ((numOfPerms(numOfNodes) * (2*numOfNodes+2) * 
            (2*numOfNodes+1))/((numOfNodes+1)*(numOfNodes+2)));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 2022-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多