此问题的基础:
今年夏天我将获得CS学位,而不是曾经有一位教授强调Stack的重要性。但是,我有多个项目都专注于递归的使用。我发现递归很有用且令人兴奋,我在个人项目中经常使用它。
我最近去过面试,面试官对他们问题的递归解决方案感到非常失望。他们想要Stack解决方案。我做了很多研究,但我还不确定何时使用它。
鉴于以下演示:
public class TestCode {
static long startTime = 0;
static long stopTime = 0;
static long totalTime = 0;
public static void main(String[] args) throws IOException {
int x = 10000;
startTime = System.currentTimeMillis();
recursiveMethod(x);
System.out.println();
stopTime = System.currentTimeMillis();
totalTime = stopTime - startTime;
System.out.println(totalTime);
System.out.println();
startTime = System.currentTimeMillis();
stackMethod(x);
System.out.println();
stopTime = System.currentTimeMillis();
totalTime = stopTime - startTime;
System.out.println(totalTime);
}
public static void recursiveMethod(int a){
if(a >= 0){
recursiveMethod(a - 1);
System.out.println("Recursion: " + a + " ");
}
}
public static void stackMethod(int a){
Stack<Integer> myStack = new Stack<Integer>();
while(a >= 0){
myStack.push(a);
a--;
}
while(myStack.isEmpty() == false){
a = myStack.pop();
System.out.println("Stack: " + a + " ");
}
}
}
两种解决方案都在大约200毫秒内完成。通过添加零来更改x
的值:x = 100000
会给我一个StackOverflowError(在递归方法上)。
当我注释掉SAME值为x
的递归解决方案时,程序运行成功,这意味着Stack解决方案远远超出了递归解决方案的限制。
问题
答案 0 :(得分:10)
为什么递归解决方案产生的StackOverflowError与Stack解决方案的迭代次数相同,但Stack解决方案不会出错?
递归使用线程堆栈,并且具有更低的限制。 STack使用堆,这个更大,但最终会出现OutOfMemoryError。
如果Stack解决方案更强大并且使用更少内存,您何时会使用递归解决方案?
速度慢,写入更难,更容易出错并且占用更多内存。只是限制要高得多。
我看到很多人在Stacks上使用递归,这是因为递归更容易&#34;虽然效率低得多? (3行代码与本例中的7行)。
你还没有预热代码,说哪个更有效率。我会忽略前10,000次迭代或第一次运行时间。
虽然我知道你不能说为什么其他人都使用递归,
通常递归的效率低于使用迭代的效率,但是使用递归时不能轻易地重构某些问题。使用Java中的迭代,95%的问题更有效。
我想对它的使用提出质疑,而不是使用它,因为&#34;其他人都会这样做。&#34;如果没有充分理由的话。
大多数时候人们使用递归是因为它更简单,更快,但它可能会耗尽堆栈空间,在极少数情况下你必须使用Stack或ArrayList,它比Stack更有效。
答案 1 :(得分:2)
应该记住一件事:从数学和信息技术的角度来看,递归和迭代是等价的。
答案 2 :(得分:1)
大多数机器架构使用固定大小的堆栈,因此递归算法的内存量有限。但是,您分配的显式堆栈可以增长到主内存的大小;因此它有更多的空间可供使用。将它与递归堆栈每帧必须包含更多数据然后显式堆栈的事实相结合,您可以看到为什么堆栈实现更有效。
递归算法通常看起来更优雅;但基于堆栈的算法通常是出于这些原因的更好选择。只有当递归级别的数量紧密限制时才应考虑递归算法。
答案 3 :(得分:1)
为什么递归解决方案产生的StackOverflowError与Stack解决方案的迭代次数相同,但Stack解决方案不会出错?
因为递归比使用堆栈使用更多内存?它说哪些都应该在相同的迭代次数下失败?
如果Stack解决方案更强大并且使用更少内存,您何时会使用递归解决方案?
首先,向我展示一下'Stack解决方案更强大'的情况。这不是一个有意义的问题。你的第三个也不是。许多算法的递归版本更容易(a)编写和(b)理解。例如,考虑分流码算法与递归下降表达式解析器。
答案 4 :(得分:1)
递归为许多问题提供了易于阅读的简单解决方案,但它存在与其他人指出的功能堆栈大小限制相关的问题。
我个人的理论是,如果递归深度为O(log n),则可以使用递归。
为了对事物进行透视,对平衡二叉树的遍历是+/- O(log n)递归深度(虽然这可以通过堆栈轻松完成,但我在这里使用它)
但是如果你的递归深度不能在O(log n)中受到约束,那么很有可能会耗尽函数堆栈空间。如果您尝试将程序编写到flood fill,则无法使用递归。