我想创建一个具有特定深度的二叉树。 到目前为止,我的代码创建二叉树直到特定的最大深度,但也创建了具有较低最大深度的树。我将在下面说明我的问题。
到目前为止我的代码(方法称为term = Literal('True') | 'False' | '$' | quotedString.setParseAction(removeQuotes)
expr = infixNotation(term,
[
('~', 1, opAssoc.RIGHT),
(oneOf('-> <->'), 2, opAssoc.LEFT),
('&', 2, opAssoc.LEFT),
('|', 2, opAssoc.LEFT),
])
):
create
问题: 如果我输入3作为深度,它应该创建像 ONLY :
这样的树public class BT<E>{
E value;
BT<E> left, right;
public BT(E value)
{
this.value=value;
}
public BT (E value, BT left, BT right)
{
this.value = value;
this.left = left;
this.right = right;
}
private static final String[] random = {"a","b","c","d"};
public static BT create(int depth) {
if (depth > 1 && random.nextBoolean())//if not at the maximum depth
//choose randomly a,b,c,d - nextBoolean ensures it is not balanced all the time
{
String random = OPERATORS[random.nextInt(OPERATORS.length)];
return new BT(operator, create(depth-1), create(depth-1));//recursively create tree
}
else {//when node is a leaf node, make it X
String t = "x";
return new BT(t);
}
}
}
我的代码当前创建了如上所述的树,但也包括如下树:
(c) (d) (a)
(b) (a) (b) (d) (c)
(x)(x)(x)(x) (x) (x) (x)
显然这些不是深度3.我不想要这个。我只希望前者没有这些例外。
有人可以查看我的代码并告诉我我做错了什么以及如何纠正它。
答案 0 :(得分:3)
最简单的方法是创建一个调用create树函数的包装函数。
该函数将使用您的函数随机自由创建,测试它是否具有所需的深度X长度。如果是,它将返回;如果没有,它将再次调用你的函数,直到它找到一个深度正确的树
答案 1 :(得分:0)
问题是:
random.nextBoolean()
在这一行:
if (depth > 1 && random.nextBoolean())
您打算使用此语句创建不平衡树,但这也很有可能在没有任何最大深度分支的情况下创建树。您只需要在递归的早期连续几次返回 false ,就会产生不良结果。鉴于有50%的机会发生这种情况,它会发生比你想象的更多!要保证至少一个具有最大深度的分支,您需要更多的处理。
一个建议可能是预先确定树中将达到最大深度的一个或多个分支,并让其他分支机会成为可能。当您使用二叉树时,可以使用布尔值来完成:
int depth = 3;
boolean[] branch = new boolean[depth];
for (int i = 0; i < branch.length; i++) {
branch[i] = random.nextBoolean();
}
一旦你有了这个,就像现在一样生成你的树。完成后,按照boolean []的说明在树中移动,使用左侧为true,右侧为false。如果您发现特定布尔值缺少子节点,并且您没有达到最大深度,请创建该子节点并继续。这不是一种特别有吸引力的方式,但它便宜又快捷。
一旦这项工作正常,您可以添加更多复杂性 - 更多保证分支,以及来自这些分支的其他分支 - 以便充实树。随着您的最大深度增加,降低结束分支的机会可能是明智的,否则您将最终得到一个长的最大深度分支和较小的分支。
答案 2 :(得分:0)
如前所述,问题出现在这一行:
if (depth > 1 && random.nextBoolean())
你要做的是:
控制评估顺序:
考虑return new BT(operator, create(depth-1), create(depth-1));
将始终首先评估左侧树,然后评估右侧树。
如果其中一个树已达到所需深度,则让树木创建叶子:
我为此创建了一个布尔变量finished
首先,我们将创建一个具有所需深度的路径。然后我们将让其他路径创建一个Tree或Leaf。
private boolean finished;
public BT<E> create(int depth){
if(depth<=0) { // One tree is at desired depth
finished = true;
return new BT<E>(null);
}
if(finished) // Let the other trees set a Leaf.
if(random.nextBoolean())
return new BT<E>(null);
BT<E> temp = create(depth-1); // Control evaluation
if (random.nextBoolean()) // evaluate left and right evenly distributed
return new BT<E>(null, temp, create(depth-1));
else return new BT<E>(null, create(depth-1), temp);
请注意,由于
,创建的树将比稀疏更稀疏if(finished)
if(random.nextBoolean())
return new BT<E>(null);
您可能希望使随机变量取决于当前路径的数量。