JavaScript递归理解(一)

先举个栗子:求n个数字的和 n=5 ------->5+4+3+2+1

function getSum(x) {
        if (x==1){
          return 1
        }
        return x+getSum(x-1);
    };

    var sum=getSum(5);
    console.log(sum);
    console.log(getSum(10));

执行过程:
代码执行getSum(5)—>进入函数,此时的x是5,执行的是5+getSum(4),此时代码等待(即 5+getSum(4) 代码先不进行计算);
先执行getSum(4),进入函数,执行的是4+getSum(3),等待;
先执行getSum(3),进入函数,执行3+getSum(2),等待;
先执行getSum(2),进入函数,执行 2+getSum(1);等待,
先执行getSum(1),执行x==1的判断,return 1,此时getSum(1)的结果是1,函数开始 往回执行
继续执行:
getSum(2)---->2+getSum(1)此时的结果是2+1
getSum(3)---->3+getSum(2) 此时的结果是3+2+1
getSum(4)---->4+getSum(3) 此时的结果是4+3+2+1
getSum(5)---->5+getSum(4) 此时的结果是5+4+3+2+1

在数学与计算机科学中,递归(Recursion)是指在函数的定义中使用函数自身的方法。顾名思义,其包含了两个意思:递 和 归。
在这里插入图片描述
递归就是有去(递去)有回(归来),如图所示。“有去”是指:递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决。就像上面例子中的钥匙可以打开后面所有门上的锁一样,“有回”是指 : 这些问题的演化过程是一个从大到小,由近及远的过程,并且会有一个明确的终点(临界点),一旦到达了这个临界点,就不用再往更小、更远的地方走下去。最后,从这个临界点开始,原路返回 到原点,原问题解决。

递归的基本思想就是把规模大的问题转化为规模小的相似的子问题来解决。特别地,在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况,这也正是递归的定义所在。格外重要的是,这个解决问题的函数必须 有明确的结束条件,否则就会导致无限递归的情况。

递归的数学模型其实就是 数学归纳法。数学归纳法适用于将解决原问题转化为解决它的子问题,而它的子问题又变成子问题的子问题,而且我们发现这些问题其实都是一个模型,也就是说存在 相同的逻辑 归纳处理项。当然有一个是例外的,也就是 归纳结束的那一个处理方法不适用于我们的归纳处理项 ,当然也不能适用,否则我们就无穷归纳了。总的来说,归纳法主要包含以下三个关键要素:

步进表达式:问题蜕变成子问题的表达式
结束条件:什么时候可以不再使用步进表达式(例外的处理)
直接求解表达式:在结束条件下能够直接计算返回值的表达式

事实上,这也正是某些数学中的数列问题在利用编程的方式去解决时可以使用递归的原因,比如著名的斐波那契数列问题。

递归的三要素:

1. 明确递归终止条件:递归就是有去有回,既然这样,那么必然应该有一个明确的临界点,程序一旦到达了这个临界点,就不用继续 往下递去 而是开始实实在在的 归来。换句话说,该临界点就是一种简单情境,可以防止无限递归。
2. 给出递归终止时的处理办法:在递归的临界点存在一种简单情境,在这种简单情境下,应该直接给出问题的解决方案。一般地,问题的解决方案是直观的、容易的。
3. 提取重复的逻辑,缩小问题规模:递归问题必须可以分解为若干个规模较小、与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决。从程序实现的角度而言,需要抽象出一个干净利落的重复的逻辑,以便使用相同的方式解决子问题。

递归算法的编程模型:

模型一: 在递去的过程中解决问题

function recursion(大规模){
    if (end_condition){      // 明确的递归终止条件
        end;   // 简单情景
    }else{            // 在将问题转换为子问题的每一步,解决该步中剩余部分的问题
        solve;                // 递去
        recursion(小规模);     // 递到最深处后,不断地归来
    }
}

模型二: 在归来的过程中解决问题

function recursion(大规模){
    if (end_condition){      // 明确的递归终止条件
        end;   // 简单情景
    }else{            // 先将问题全部描述展开,再由尽头“返回”依次解决每步中剩余部分的问题
        recursion(小规模);     // 递去
        solve;                // 归来
    }
}
  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 递归是一种编程技巧,其中一个函数调用自身。在 JavaScript 中,递归方法可以用来解决复杂的问题,并使代码更简洁易读。 递归的基本模型包括以下几个步骤: 1. 定义递归终止条件:当递归达到一定的深度时,必须终止递归。 2. 分治:将问题分解为规模更小的子问题。 3. 调用自身:通过解决子问题来解决整个问题。 4. 记录结果:在递归的过程中,记录每一步的结果。 下面是一个简单的递归例子,计算阶乘: ``` function factorial(n) { if (n === 0) { return 1; } return n * factorial(n - 1); } ``` 在这个例子中,递归终止条件是 `n` 为 0,分治的子问题是计算 `n-1` 的阶乘,调用自身的方式是通过函数 `factorial` 调用,并将计算结果返回。 ### 回答2: 递归是一种在编程中常见的技巧,特别在JavaScript中,递归方法经常被用来解决问题。递归是指一个函数调用自身的过程。下面是关于JavaScript递归方法的一些重要信息: 1. 递归方法必须包含一个终止条件,否则函数将无限地调用自身。这个终止条件通常是某个特定条件的判断,一旦满足了该条件,递归将停止。 2. 递归方法必须能够将问题分解为更小的子问题,同时保持问题的解决方案是相同的。 3. 递归方法可以方便地解决一些复杂的问题,例如树和图的遍历,阶乘计算等。 4. 使用递归方法时需要小心,因为它可能会导致性能问题。递归过程中使用大量的函数调用,可能导致堆栈溢出。 5. 尽管递归方法可以让代码更简洁和易于理解,但在某些情况下,使用循环可能更高效和可维护。因此,在选择使用递归方法之前,需要仔细权衡。 总的来说,JavaScript递归方法是一种强大而灵活的编程技巧,可以解决各种问题。但在使用时需要注意终止条件和性能问题,以确保代码的正确性和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值