我有一棵树,其中叶子用L标记,非叶节点用I标记。我得到了树的前序遍历。一个例子是IIILLILILLIIILLLIILILLL。我必须为这个包含的字符串构建霍夫曼树。我最初为我的参数传入一个新的Root(),0和我的treeString。 TreeString将是粘贴在上面的I' s和L' s。由于某种原因,我的代码会导致抛出StackOverflow异常。对于makeTree方法,我的代码如下:
public static void makeTree (BinaryNodeInterface<Character> root, int start, String treeString)
{
if (treeString.charAt(start)=='L'){
root.setLeftChild(null);
root.setRightChild(null);
return;
}
BinaryNodeInterface<Character> leftSide = new BinaryNode<Character>();
root.setLeftChild(leftSide);
makeTree(root.getLeftChild(), start++, treeString);
BinaryNodeInterface<Character> rightSide = new BinaryNode<Character>();
root.setRightChild(rightSide);
makeTree(root.getRightChild(), start++, treeString);
}
我不知道是什么导致了stackoverflow异常被抛出。我认为我在开始时的基本情况会返回并处理它。
答案 0 :(得分:0)
我认为这是问题:
makeTree(root.getLeftChild(), start++, treeString);
我不确定你的方法是什么,但看起来如果你看到I
,你的计划就是转到左边的节点,并开始检查从下一个字符开始的字符串。
无限递归的原因是start++
是一个后增量运算符,这意味着它为您提供当前值start
,然后递增它。因此,每次makeTree
调用自身时,它会使用相同版本的start
调用自身,从而在输入字符串中查看相同的I
。
但是,将其更改为++start
将无法正常工作。(可能会避免堆栈溢出,但无法正常工作。)原因是当您调用时makeTree
,你想给它一个你希望递归调用开始查找的字符串的起始位置 - 但你也希望递归调用告诉它它消耗了多少字符串。这是必要的,因为makeTree
在getLeftChild
上递归调用自己之后,您将在getRightChild
上再次调用它,并且您需要使用正确的起点调用它。
请注意,每个递归调用都有自己的start
副本。因此,当makeTree
调用自身,第二个makeTree
增加start
时,这对第一个start
看到的makeTree
没有影响。
你会以某种方式需要每个递归makeTree
来告诉它的调用者它消耗了多少字符串。也许,最简单的方法是将返回类型更改为int
;您可以决定是否希望函数结果为消耗的字符数,或者停止扫描的索引,或类似的东西。然后,在递归调用makeTree
之后,使用函数result调整start
参数。确保makeTree
在叶子和非叶子情况下都返回正确的结果。小心避免一对一的错误。
答案 1 :(得分:0)
您无法仅从preOrder列表创建树。 至少你需要inorder遍历或者如果是完整的树,那么你也可以使用postorder。