前言
- 递归完成1到100的累加
递归
递归调用是一种特殊的调用形式,指的是方法自己调用自己的形式。
查看下面的示例
function neverEnd() {
console.log('neverEnd')
neverEnd()
}
method 会先输出 neverEnd ,然后再调用自己导致无限递归(infiniterecursion)。当然这一般是我们需要避免的状况。
在进行递归操作的时候,我们需要满足以下几个条件:
-
递归调用必须有结束条件
-
每次调用的时候都需要根据需求改变传递的参数内容
下面是递归的一个示例,求某个数的阶乘。(5的阶乘 5! = 5 * 4 * 3 * 2 * 1)
function factorial(n) {
if (n === 1) {
return n
}
return n * factorial(n - 1)
}
factorial(5) // 120
5 * factorial(4)
5 * (4 * factorial(3))
5 * (4 * (3 * factorial(2)))
5 * (4 * (3 * (2 * factorial(1))))
5 * (4 * (3 * (2 * 1)))
5 * (4 * (3 * 2))
5 * (4 * 6)
5 * 24
120
使用递归时需要注意如下事项:
-
递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以用循环的方式来实现。
-
使用递归时需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当一个函数调用,栈就会加一层,每当函数返回,找就会减一层。由于栈的大小不是无限的,所以递归调用的次数过多,会导致栈溢出。
下面看几个递归的示例:
- 使用递归来计算从 x 加到 y 的结果
function add(x, y) {
if (x === y) {
return x
}
return x + add(x + 1, y)
}
// 1 + 2 + 3 + ... + 100
add(1, 100) // 5050
或者
function add(x, y) {
if (x === y) {
return y
}
return y + add(x, y - 1)
}
// 100 + 99 + 98 + ... + 1
add(1, 100) // 5050
- 使用递归实现斐波那契数列
// 0、1、1、2、3、5、8、13、21、34……
// F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
function fibonacci(n) {
if (n === 0) {
return 0
}
if (n === 1) {
return 1
}
return fibonacci(n - 1) + fibonacci(n - 2)
}
fibonacci(3) // fibonacci(2) + fibonacci(1) = fibonacci(1) + fibonacci(0) + fibonacci(1) = 1 + 0 + 1 = 2
总结
- 递归完成1到100的累加
function add(x, y) {
if (x === y) {
return x
}
return x + add(x + 1, y)
}
// 1 + 2 + 3 + ... + 100
add(1, 100) // 5050