从Preorder Traversal构建二进制树:堆栈溢出错误

时间:2014-12-07 01:10:18

标签: java recursion tree huffman-code preorder

我有一棵树,其中叶子用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异常被抛出。我认为我在开始时的基本情况会返回并处理它。

2 个答案:

答案 0 :(得分:0)

我认为这是问题:

makeTree(root.getLeftChild(), start++, treeString);

我不确定你的方法是什么,但看起来如果你看到I,你的计划就是转到左边的节点,并开始检查从下一个字符开始的字符串。

无限递归的原因是start++是一个后增量运算符,这意味着它为您提供当前值start,然后递增它。因此,每次makeTree调用自身时,它会使用相同版本的start调用自身,从而在输入字符串中查看相同的I

但是,将其更改为++start将无法正常工作。(可能会避免堆栈溢出,但无法正常工作。)原因是当您调用时makeTree,你想给它一个你希望递归调用开始查找的字符串的起始位置 - 但你也希望递归调用告诉它它消耗了多少字符串。这是必要的,因为makeTreegetLeftChild上递归调用自己之后,您将在getRightChild上再次调用它,并且您需要使用正确的起点调用它。

请注意,每个递归调用都有自己的start副本。因此,当makeTree调用自身,第二个makeTree增加start时,这对第一个start看到的makeTree没有影响。

你会以某种方式需要每个递归makeTree来告诉它的调用者它消耗了多少字符串。也许,最简单的方法是将返回类型更改为int;您可以决定是否希望函数结果为消耗的字符数,或者停止扫描的索引,或类似的东西。然后,在递归调用makeTree之后,使用函数result调整start参数。确保makeTree在叶子和非叶子情况下都返回正确的结果。小心避免一对一的错误。

答案 1 :(得分:0)

您无法仅从preOrder列表创建树。 至少你需要inorder遍历或者如果是完整的树,那么你也可以使用postorder。