抢先递归算法是否也是递归的?
根据定义:
非先决递归 :如果一个函数根据其一个参数调用自己,那么这样的递归称为非先行递归(Non-Premptive Recursion)。 示例:阿克曼函数是非抢先递归的一个例子
private static int Foo(int i)
{
if (i == 1000000)
return i;
if (i % 100 == 0)
Console.WriteLine(i);
return Foo(Foo(i+1));//last statement of the function
}
这里对Foo
的递归调用是函数的最后一个语句,并不是表达式的一部分,它使它成为尾递归调用。 但另一方面,由于Foo
函数已被称为参数,所以它将导致创建调用堆栈帧,在达到终止条件之前这些帧不能被丢弃。
在尾递归中,编译器可以优化尾递归调用,因为它不需要维护调用栈帧。 所以我的问题是 - 我的递归调用上面的代码段中的Foo
真的是一个尾递归调用?
非抢先递归算法是否也可以递归?
是。
我在上面的代码片段中对Foo
递归调用真的是一个尾递归调用吗?
哪一个? 有两个递归调用:
…(Foo(i+1))…
- 不是尾递归 return Foo(…);
- 尾递归 外部的尾递归可以被优化:
private static int Foo(int i) {
while (i != 1000000) {
if (i % 100 == 0) Console.WriteLine(i);
i = Foo(i+1);
}
return i;
}
编译器可能会推断Foo
始终返回1000000
(如果它返回),因此会将该方法进一步重写为另一个尾递归,但这需要高级推理,而不是简单的转换:
private static int Foo(int i) {
if (i != 1000000) {
if (i % 100 == 0) Console.WriteLine(i);
} else {
return i;
}
return Foo(i+1);
}
然后可以通过尾递归规则将其转换为
private static int Foo(int i) {
while (i != 1000000) {
if (i % 100 == 0) Console.WriteLine(i);
i = i+1;
}
return i;
}
链接地址: http://www.djcxy.com/p/80695.html
上一篇: preemptive recursive algorithm be tail recursive as well?
下一篇: Tail recursion in R