有人可以解释一下我们在这里实际计算可能的BST的方式。我理解基本部分,我们依赖实际的左树和右子树计数来获得总计数。我很难理解循环。
public static int countTrees(int numKeys){
if(numKeys<=1){
return(1);
}
else{
// there will be one value at the root, with whatever remains
// on the left and right each forming their own subtrees.
// Iterate through all the values that could be the root...
int sum=0;
int left,right,root;
for(root=1;root<=numKeys;root++){
left=countTrees(root-1);
right=countTrees(numKeys-root);
// number of possible trees with this root == left*right
sum+=left*right;
}
return(sum);
}
}
答案 0 :(得分:2)
显然,这与二进制搜索树无关,一般与二叉树无关。该实现使用归纳参数来计算具有n
个节点的可能二叉树的数量。
第一种情况是基本情况,其中一个onr没有节点可能只能安排在一棵树中。
第二种情况通过假设在n
个节点之外,每个节点可以是根节点来计算节点数,这意味着剩余的n-1
节点将被分配到左侧和右子树,其中递归评估所有可能的分布组合;请注意,显然节点是有区别的,这意味着同构树被多次计数。
在递归评估左右子树的可能实现之后,将得到的可能性相乘以获得整个树的可能实现的总数。
例如,假设您要评估3
个节点的树数,对应于节点集{1,2,3}
。该数字大于1
并且每个节点都可以是根节点,从而导致循环执行3次迭代,如下所示。
1 is the root, 2 remaining nodes to distribute.
2 is the root, 2 remaining nodes to distribute.
3 is the root, 2 remaining nodes to distribute.
2
节点的评估将是相同的,因此我们仅为第一次调用扩展呼叫。对于2
个节点,对应于节点集{1,2}
。该数字大于1
,导致循环进行2次迭代,如下所示。
1 is the root, 1 remaining node to distribute.
2 is the root, 1 remaining node to distribute.
1
节点的评估将是相同的,即确实存在1
个可能性。
1 is the root, 1 remaining node to distribute;
the 1 node can be in either the left or the right subtree,
resulting in 1 possiblity each, which is 2 possibilities in total.
这意味着调用2
个节点的结果将为2
。
回到上面的评估,我们获得以下内容。
1 is the root, 2 remaining nodes to distribute;
possibilites:
2 in the left subtree, 0 in the right subtree;
results in 4*1 = 4 possibilities.
1 in the left subtree, 1 in the right subtree;
results in 1*1 = 1 possibilities.
0 in the left subtree, 2 in the right subtree;
results in 1*4 = 4 possibilities.
总结这些可能性,一旦选择了根,就有4 + 1 + 4 = 9种可能性来安排具有3
个节点的树;但总的来说,有3
个方法可以选择根,这会给出总结果。
1 is the root, 2 remaining nodes to distribute;
results in 9 possibilites.
2 is the root, 2 remaining nodes to distribute;
results in 9 possibilites.
3 is the root, 2 remaining nodes to distribute;
results in 9 possibilites.
如果总结一下,这可能是9+9+9=27
个可能的树。