对递归的理解和学习

递归是一种解决问题的方法,它从解决问题的各个小部分开始,直到解决最初的大问题.递归通常涉及函数调用自身.

下面通过例子来说明.

一.计算一个数的阶乘

作为递归的第一个例子,来看下如何计算一个数的阶乘.数n的阶乘,定义为n!,表示从1到n的整数的乘积.

5的阶乘表示为5!,和5*4*3*2*1相等,结果是120.

(1)迭代阶乘

如果尝试表示计算任意数n的阶乘的步骤,可以将步骤定义如下:(n)*(n-1)*(n-2)*(n-3)*...*1 .

可以使用循环来写一个计算一个数阶乘的函数,如下所示:

        function factorialIterative(number) {
            if (number < 0) return undefined
            let total = 1
            for (let n = number; n > 1; n--){
                total = total * n
            }
            return total
        }
        console.log(factorialIterative(5));

最后输出结果是120.

我们可以从给定的number开始计算阶乘,并减少n,直到它的值为2,因为1的阶乘还是1,而且它已经被包含在total变量中了.零的阶乘也是1.负数的阶乘不会被计算.

(2)递归阶乘

现在我们试着用递归来重写factorialIterative函数.

        function factorial(n) {
            if (n === 1 || n === 0) {//基线条件
                return 1
            }
            return n * factorial(n - 1)//递归调用
        }
        console.log(factorial(5))//120

二.斐波那契数列

斐波那契数列是另一个可以用递归解决的问题.它是一个由0,1,1,2,3,5,8,13,21,34等数组成的数列.数2由1+1得到,数3由1+2得到,数5由2+3得到,以此类推,斐波那契数列的定义如下:

位置0的斐波那契数列是零;

1和2的斐波那契数是1;

n(此处n>2)的斐波那契数是是(n-1)的斐波那契数加上(n-2)的斐波那契数.

(1)迭代求斐波那契数

我们用迭代的方式实现了fibonacci函数,如下所示:

function fibonacciIterative(n) {
            if (n < 1) return 0
            if (n <= 2) return 1
            let fibNMinus2 = 0
            let fibNMinus1 = 1
            let fibN = n
            for (let i = 2; i <= n; i++) {//n >=2
                fibN = fibNMinus1 + fibNMinus2//f(n-1)+f(n-2)
                fibNMinus2 = fibNMinus1
                fibNMinus1 = fibN
            }
            return fibN
        }

(2)递归求斐波那契数

fibonacci函数可以写成这样:

        function fibonacci(n) {
            if (n < 1) return 0
            if (n <= 2) return 1
            return fibonacci(n - 1) + fibonacci(n - 2)
        }

(3)记忆化斐波那契数

还有第三种写fibonacci函数的方法,叫做记忆法.记忆法是一种保存前一个结果的值的优化技术,类似于缓存.如果我们分析在计算fibonacci(5)时的调用,会发现fibonacci(3)被计算了两次,因此可以将它的结果存储下来,这样当需要再次计算它的时候,我们就已经有了它的结果了.

下面的代码展示了使用记忆化的fibonacci函数:

       function fibonacciMemoization() {
            const memo = [0, 1]
            const fibonacci = (n) => {
                if (memo[n] !== null) return memo[n]
                return memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo)
            }
            return fibonacci
        }

在上面代码中,我们声明了一个memo数组来缓存所有的计算结果.如果结果已经被计算了,我们就返回它,否则计算该结果并将它加入缓存.

猜你喜欢

转载自blog.csdn.net/huihui_999/article/details/129976138
今日推荐