如何找到可能的二叉树拓扑排列的数量?

时间:2012-07-09 14:40:19

标签: java algorithm tree binary-tree catalan

给定二进制树节点(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;
    } 

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

3 个答案:

答案 0 :(得分:5)

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

recurrence relation for C_n

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

closed formulae

所有这些都适用于代码实现,并且比任何递归方法都快得多。

答案 1 :(得分:4)

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

直观地说,我会采用递归方式。

  1. 将一个节点用作父节点
  2. 将所有可能的划分分为两组,递归调用两个集合的函数
  3. 将每个部门的两组结果相乘,并总结所有部门的产品
  4. 返还总和
  5. 但在实施之前,我会确保没有简单的公式。我没有找到一个快速(这并不意味着没有一个)。

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

答案 2 :(得分:2)

尝试这种递归方法:

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)));
}