什么是递归?

300 阅读3分钟

一.递归:

1.1递归的概念:

  • 就是在运行的过程中自己调用自己

1.2递归小故事:

1,从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?“从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’”

2,大雄在房里,用时光电视看着从前的情况。电视画面中的那个时候,他正在房里,用时光电视,看着从前的情况。电视画面中的电视画面的那个时候,他正在房里,用时光电视,看着从前的情况……

1.3 递归模板

我们知道递归必须具备两个条件,一个是调用自己,一个是有终止条件。这两个条件必须同时具备,且一个都不能少。并且终止条件必须是在递归最开始的地方,也就是下面这样:

  • 如图:

image.png

  • 不能把终止条件写在递归结束的位置,下面这种写法是错误的 如图:

image.png

  • 如果这样的话,递归永远退不出来了,就会出现堆栈溢出异常(StackOverflowError)。

我对递归的理解是先往下一层层传递,当碰到终止条件的时候会反弹,最终会反弹到调用处

1.4案例讲解:

(一)阶乘:

  • 图例

image.png 代码演示:

multiplication 阶乘
function cheng(n){
   if(n==1) return 1
   return n*cheng(n-1)
}
let result =cheng(8)
console.log(result);

(二)斐波那契数列:

1.斐波那契数列的概念

    斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。

    斐波那契数列指的是这样一个数列:

    0112358132134558914423337761098715972584418167651094617711……

    它的规律是:这个数列从第 3 项开始,每一项都等于前两项之和。

    在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*),显然,斐波那契数列是一个线性递推数列。

2.斐波那契数列的实现

  • 常用的实现斐波那契数列的方法分为两大类:递归和循环。
    • 图例:

image.png

  • 代码演示:
 斐波那契数列  兔子数列    112358132134
  死公式:  F(0)=0F(1)=1, F(n)=F(n - 1)+F(n - 2)

    `递归`
    function fib(n) {
        if (n <= 1) {
            return 1
        }
        return fib(n - 1) + fib(n - 2)

    }
    console.log(fib(5));

image.png

(三)数组递归求和:

  • A代码演示:
let arr=[100,200,300,[400,500,[49,59,80,[232,535,77]]]]
let total=0;
function di(arr){ 
    arr.forEach(item=>{
        if(typeof item=='number'){
            total+=item
        }else{ 
            return di(item)
        }
    })
}
di((arr))
console.log(total);  //2532
  • B代码演示:
例:let arr1 = [
  {
    name: "张三",
    money: 100,
    children: [
      { name: "张欢欢", money: 200 },
      {
        name: "张乐乐",
        money: 100,
        children: [
          { name: "张小欢", money: 300 },
          { name: "张小乐", money: 400 },
        ],
      },
    ],
  },
  {
    name: "李四",
    money: 100,
    children: [
      { name: "李红红", money: 500 },
      { name: "李明明", money: 600 },
    ],
  },
];

解:let num = []
function dep(arr1) {
    // console.log(arr1);
    arr1.forEach(item => {
        //判断children
        if (item.children) {
            dep(item.children)
            num+= dep(item.children.money)
        }else{ 
            return item.money
        }

    })
}
dep(arr1)
console.log(num);

(四)数组的扁平化就是 高维数组转低位数组

 arr=[1,2,[3,4,[5,6,[7]]]]
    数组转地维的方法有两种
   ` 第一种` 利用递归实现 或者使用es6新增的flat
    let newArr=arr.flat(4)
    console.log(newArr);  //[1, 2, 3, 4, 5, 6, 7]
    let newArr=arr.flat(Infinity)   //infinity就是无穷大的无论嵌套多少层
    console.log(newArr);   //[1, 2, 3, 4, 5, 6, 7]
     `第二种方法就是利用递归实现`
    function lowDown(params){ 
        let newArr1=[]
        if(Array.isArray(params)){
            params.forEach(item=>{
                if(Array.isArray(item)){
                    newArr1.push(...lowDown(item))
                }else{
                    newArr1.push(item)
                }
            })
        }
        return newArr1
    }
  let new1=lowDown(arr)
  console.log(new1);  //[1, 2, 3, 4, 5, 6, 7]