【发布时间】:2015-07-12 22:48:10
【问题描述】:
从理论上(即不实际执行)确定某个树遍历递归算法在 Java 中会产生堆栈溢出的情况的最佳方法是什么?
为了澄清我的问题,请考虑以下示例。 给定一个用 Java 实现的简单二叉树:
public class Node {
private int value;
private Node left;
private Node right;
...
//in-order traversal
public void inOrder() {
if (left != null) {
left.inOrder();
}
System.out.println(value);
if (right != null) {
right.inOrder();
}
}
}
在此算法中,嵌套递归调用的最大数量与树的深度成线性关系。 那么如何估计允许有序遍历算法(或类似算法)在不引发堆栈溢出错误的情况下完成的树的最大深度?
如果最大堆栈大小是由线程通过-Xss option 分配的,那么将这个数字除以我的递归算法使用的每个堆栈帧的估计值是否正确?
通过将参数和局部变量的大小添加到程序计数器的大小来估计每个堆栈帧的大小是否正确,其中程序计数器的大小取决于架构(32位与64位等) ..)。
我还错过了什么吗?
更新:
我知道递归算法可以转换为迭代算法以避免堆栈溢出错误。这只是一个关于递归算法的理论问题。
【问题讨论】:
-
可能有点跑题了,但是如果您担心这里的堆栈溢出,为什么不把它变成一个循环并将值放入处理数组中?
-
我同意@JFPicard。每个递归算法都可以轻松转换为迭代算法。
-
我会回答你所有的“是否正确”的问题:)
-
感谢您的 cmets。刚刚更新了我的问题。
-
所有使用方法调用的算法都会溢出堆栈,问题是堆栈调用可以达到多深,以及是否取决于输入。如果对树进行递归调用,则取决于树的深度。所以通常一个平衡的树永远不会那么深来触发这个(但你可以很容易地构建病理案例)。
标签: java recursion stack-overflow stack-frame