繁体   English   中英

通过预遍历构建二叉树:堆栈溢出错误

[英]Build Binary Tree from Preorder Traversal: Stack Overflow Error

我有一棵树,叶子用L标记,非叶子节点用I标记。得到树的预遍历。 一个例子是IIILLILILLIIILLLIILILLL。 我必须为此包含的字符串构建霍夫曼树。 我最初传入一个新的Root(),0和我的treeString作为参数。 TreeString是上面带有I和L的字符串。 由于某种原因,我的代码导致引发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异常。 我认为一开始我的基本情况将返回并处理。

我相信这是问题所在:

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

我不确定您的处理方法是什么,但是如果您看到I ,则您的计划是转到左节点,然后开始检查从下一个字符开始的字符串。

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

但是,将其更改为++start将无法正常工作。 (这可以避免堆栈溢出,但是不能正常工作。)原因是,当您调用makeTree ,您想给它一个字符串的起始位置,您希望在该位置开始递归调用,但是您还希望递归调用告诉它消耗了多少字符串。 这是必要的,因为在makeTreemakeTree上递归调用自身getLeftChild ,您将在getRightChild再次调用它,并且需要以正确的起点进行调用。

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

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

您不能仅从preOrder列表创建树。 至少您还需要顺序遍历,或者如果是完整树,则也可以使用后序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM