我正在使用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();
}
任何帮助或提示都将不胜感激, 谢谢。
答案 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语句旁边递归调用leftChild
和rightChild
上的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)
几乎肯定是无限制的递归。我猜这是在getLeftChild
或getRightChild
的实施中犯了一个错误。我建议你在调试器中单步执行,我打赌你会很快看到它的位置。
但是,如果您有一个非常深的树,您可能会发现堆栈溢出异常是合法的,在这种情况下,您需要重新访问该算法。传统的尾递归技术appears to be hard to achieve in Java.