在树中递归搜索时出现Stackoverflow错误

时间:2014-03-17 13:00:26

标签: java tree recursive-datastructures

我正在使用Java实现Shannon / Fano算法,我通过计算文本文件中符号的频率来实现这一点,之后我将所有这些值放在树中。问题是,当我在树中搜索某个符号时,我还必须更新相应符号的代码(例如,如果我向左追加0,否则为1)并以递归方式执行此操作,我收到堆栈溢出错误。以下是我的代码:

private String getNodeValue(Node node, String symbol) {
    if (node.getLeftChild() != null) {
        if (node.getLeftChild().getData().equalsIgnoreCase(symbol)) {
            node.updateCode(0);
            return node.getData() + "";
        }
    } else if (node.getRightChild() != null) {
        if (node.getRightChild().getData().equalsIgnoreCase(symbol)) {
            node.updateCode(1);
            return node.getData() + "";
        }
    }


    Node nextLeftNode = node.getLeftChild().getLeftChild();
    if (nextLeftNode != null) {
        getNodeValue(nextLeftNode, symbol);
    }

    Node nextRightNode = node.getRightChild().getRightChild();
    if (nextRightNode != null) {
        getNodeValue(nextRightNode, symbol);
    }

    // if symbol is not found return null
    return null;
}

,当调用node.getData()时,在方法的第一行触发stackoverflow错误。这是我的堆栈跟踪:

Exception in thread "main" java.lang.StackOverflowError
at ro.uvt.it.datastractures.Node.getData(Node.java:47)
at ro.uvt.it.datastractures.Node.getData(Node.java:47)
at ro.uvt.it.datastractures.Node.getData(Node.java:47)

这是我的getData()方法:

public String getData() {
    return this.getData();
}

任何帮助或提示都将不胜感激, 谢谢。

2 个答案:

答案 0 :(得分:1)

您的代码中存在许多错误。

正如您在堆栈跟踪中所展示的那样,无限递归在getData方法中,而不在getNodeValue方法中,因此您需要发布getData方法的源代码。

但是getNodeValue方法也存在很多错误。

你的前两个if语句具有完全相同的条件:

if (node.getData().equalsIgnoreCase(symbol)) {

else if (((String) node.getData()).equalsIgnoreCase(symbol)) {

这些if语句中的返回值将空字符串附加到getData()的结果,该结果已返回String。用以下内容替换它们:

return node.getData();

只是一种不同的写入方式,因为getData()已经返回一个String,所以再次转换为String并没有什么区别。

你的if语句旁边递归调用leftChildrightChild上的getNodeValue,但它们永远不会返回任何内容,因此一旦你超过了代码,你总是会在代码中返回null方法中前两个相同的if语句。

你的代码应该是:

if (node.getLeftChild() != null) {
    String found = getNodeValue(node.getLeftChild(), symbol);
    if (found != null) {
        return found;
    }
}
if (node.getRightChild() != null) {
    String found = getNodeValue(node.getRightChild(), symbol);
    if (found != null) {
        return found;
    }
}

答案 1 :(得分:0)

几乎肯定是无限制的递归。我猜这是在getLeftChildgetRightChild的实施中犯了一个错误。我建议你在调试器中单步执行,我打赌你会很快看到它的位置。

但是,如果您有一个非常深的树,您可能会发现堆栈溢出异常是合法的,在这种情况下,您需要重新访问该算法。传统的尾递归技术appears to be hard to achieve in Java.