JS学习(13)递归

101 阅读2分钟

前言

  • 递归完成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

screenshot-20240726-144739.png

使用递归时需要注意如下事项:

  • 递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以用循环的方式来实现。

  • 使用递归时需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当一个函数调用,栈就会加一层,每当函数返回,找就会减一层。由于栈的大小不是无限的,所以递归调用的次数过多,会导致栈溢出。

下面看几个递归的示例:

  1. 使用递归来计算从 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
  1. 使用递归实现斐波那契数列
// 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