抢先递归算法是否也是递归的?
根据定义:
非先决递归 :如果一个函数根据其一个参数调用自己,那么这样的递归称为非先行递归(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;
}
上一篇: preemptive recursive algorithm be tail recursive as well?
下一篇: Tail recursion in R
