递归简单来说就是一个函数直接或间接的调用自身,当未达到递归的边界条件时函数会继续递归调用函数自身,若达到边界条件则递归返回。
普通递归执行时,每一层函数的返回都要依赖于下一层函数的返回值,系统为会开辟栈来存储每一层函数的返回点、局部变量,因此递归次数越多,需要保存的中间函数的堆栈就越多,消耗的系统资源就越多,甚至会造成栈溢出。
尾递归,上层函数会把当前的计算结果作为参数传给下层函数,函数调用总是出现在调用函数的尾部,所以没有必要保存每一次函数调用时的局部变量,只用保留最后一个函数的堆栈即可,因此性能比普通递归要好。
以下是用java实现递归与尾递归的一个例子:
public class TestRecursion {
// 斐波那契数列,普通递归实现
public static int fibonacciRecursive(int n) {
if (n
return n;
}
return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);
}
// 斐波那契数列,尾递归实现
public static int fibonacciTailRecursive(int n, int i1, int i2) {
if (n == 0) {
return i1;
}
return fibonacciTailRecursive(n - 1, i2, i1 + i2);
}
// 求n的阶乘,普通递归实现
public static int factorialRecursive(int n) {
if (n
return n;
}
return n * factorialRecursive(n - 1);
}
// 求n的阶乘,尾递归实现
public static int factorialTailRecursive(int n, int i) {
if (n
return 0;
} else if (n == 0) {
return 1;
} else if (n == 1) {
return i;
}
return factorialTailRecursive(n - 1, i * n);
}
public static void main(String[] args) {
// 斐波那契数列
System.out.println(fibonacciRecursive(9));
System.out.println(fibonacciTailRecursive(9, 0, 1));
// 求n的阶乘
System.out.println(factorialRecursive(10));
System.out.println(factorialTailRecursive(10, 1));
}
}