【发布时间】:2020-07-15 13:38:42
【问题描述】:
我确实理解递归的问题之一是堆栈深度,它可能导致非常深的递归出现问题。我也知道递归可以被显式堆栈使用代替以避免此类问题。
另一方面,递归允许代码简洁明了(我会说很漂亮),如果我没记错的话,它是所有标准教科书中介绍算法的主要方式。
我的问题比理论更实际:
我正在运行以下程序来计算在获得java.lang.StackOverflowError之前我能走多远
我的理由是,例如如果我有一个包含几千个顶点的小型图形视图,并且每次遍历的处理量最少,那么递归与迭代方法可能就没有那么重要了:
public static void foo(int i) {
if (i % 5000 == 0) {
System.out.println(i);
}
foo(i + 1);
}
public static void main(String[] args) {
foo(0);
}
输出是:
Exception in thread "main" java.lang.StackOverflowError
5000
10000
因此,我的解释是,程序会在处理超过 10000 个顶点后进行 DFS,这听起来很小。
谷歌搜索我发现当我们运行一个程序时,堆栈的默认大小是可以配置的,但我想知道这方面的行业惯例是什么?
是否为繁重的服务器程序设置显式线程堆栈大小,以便上面的示例在实践中不会成为问题?还是完全避免编写递归?还是我的例子不能真正代表一个问题?
更新
我明白上面的代码示例是一个无限递归。这样做的唯一目的是看看它在断裂之前能走多远。
【问题讨论】:
-
您发布的代码是无限递归。没有任何配置可以让它工作。
-
@khelwood:是的,我明白这一点。唯一的目的是看看它在崩溃之前能走多远。没有别的
-
据我所知,没有行业惯例,但是当您没有支持尾调用消除的语言时,最好避免递归调用。除非,也就是说,您知道递归非常浅。
-
代码干净简洁是因为它清晰简洁,而不是因为它是“递归编写的”。而且它也不能使它成为好的代码。例如,将斐波那契函数( 教科书递归的典型代表)作为递归函数实现是现实生活中最糟糕的实现,这适用于许多其他不关心自己的教科书示例他们提供的代码是否是高效的。只要保证递归本身足够浅,递归就有它的位置,并且递归的开销是微不足道的。
-
@Jim 你是对的。我会投票重新开放。
标签: java algorithm recursion optimization graph-algorithm