递归与尾递归

递归简单来说就是一个函数直接或间接的调用自身,当未达到递归的边界条件时函数会继续递归调用函数自身,若达到边界条件则递归返回。

普通递归执行时,每一层函数的返回都要依赖于下一层函数的返回值,系统为会开辟栈来存储每一层函数的返回点、局部变量,因此递归次数越多,需要保存的中间函数的堆栈就越多,消耗的系统资源就越多,甚至会造成栈溢出。

尾递归,上层函数会把当前的计算结果作为参数传给下层函数,函数调用总是出现在调用函数的尾部,所以没有必要保存每一次函数调用时的局部变量,只用保留最后一个函数的堆栈即可,因此性能比普通递归要好。

以下是用java实现递归与尾递归的一个例子:

public class TestRecursion {

    // 斐波那契数列,普通递归实现
    public static int fibonacciRecursive(int n) {
        if (n < 2) {
            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 < 2) {
            return n;
        }
        return n * factorialRecursive(n - 1);
    }

    // 求n的阶乘,尾递归实现
    public static int factorialTailRecursive(int n, int i) {
        if (n < 0) {
            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));
    }

}


你可能感兴趣的:(递归与尾递归)