递归函数

36 阅读2分钟

递归函数

一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的。用递归过程定义的函数,称为递归函数,例如连加、连乘及阶乘等。凡是递归的函数,都是可计算的

function fn(n) {
//计算 4 的阶乘
     return n * fn(n - 1)
}
    var sum = fn(4)
    console.log(sum)    // 此时打印的值 为 4 的阶乘
/*
* fn 函数 需要一个参数, 传入一个参数后 会得到这个参数的 阶乘结果
* fn(100) ->  100 的阶乘
* fn(99)  ->  99 的阶乘
* fn(4)   -> 4 的阶乘
*/

/**
* function fn(n) {
* return n * fn(n - 1)
}
* fn(4)
* 第一次调用, 传递 参数 4
* 形参 n === 4
* 函数体  return n * fn(n - 1)    ->  return 4 * fn(3)
* 计算 fn(3)  -> 计算 3 的阶乘
* 调用的时候 传参是 3
* 形参 n === 3
* 函数体 return n * fn(n - 1)     ->      return 3 * fn(2)
* 计算 fn(2)  -> 计算 2 的阶乘
* 调用的时候 传参是 2
* 形参 n === 2
* 函数体 return n * fn(n - 1)     ->      return 2 * fn(1)
* 计算 fn(1)  -> 计算 1 的阶乘
* 调用的时候 传参是 1
* 形参 n === 1
* 函数体 return n * fn(n - 1)     ->      return 1 * fn(0)
* 计算 fn(0)  -> 计算 0 的阶乘
* 调用的时候 传参是 0
* 形参 n === 0
* 函数体 return n * fn(n - 1)     ->      return 0 * fn(-1)
* .... 永无止境, 相当于写了死循环
* 100 的阶乘      100 * 99 * 98 * 97 ..... * 3 * 2 * 1*/

function fn(n) {
 if (n === 1) {
 // 说明此时想要计算 1 的阶乘, 那么我直接将 1 的阶乘的结果 return 出去
       return 1
 }
 return n * fn(n - 1)
}
var sum = fn(4)
console.log(sum)    // 24

var sum1 = fn(10)
console.log(sum1)

/*
* 第一次调用 传递的参数为 4
* 形参 n === 4
* 函数体  1. if 分支      2. return 递归调用
* 此时 分支语句 不会执行, 开始 执行 return 递归调用
* return n * fn(n - 1)        return 4 * fn(3)    == 24
* 计算 fn(3)  === 6
* 传递的 形参 n === 3
* 此时分支语句不会执行, 开始执行 return 递归调用
* return n * fn(n - 1)        return 3 * fn(2) === 6
* 计算 fn(2)  === 2
* 传递的 形参 n === 2
* 此时分支语句不会执行, 开始执行 return 递归调用
* return n * fn(n - 1)        return 2 * fn(1) === 2
* 计算 fn(1)  === 1
* 传递的 形参 n === 1
* 此时 分支语句 判断成功, 所以直接 return 1       中断函数的递归
*/