JavaScript中的递归函数是如何工作的?


本文将教你如何使用递归方法创建一个JavaScript递归函数——**一个调用自身的函数**。递归的过程就是函数自己调用自己。递归函数是指反复调用自身的函数。递归函数中总是包含一个停止自调用的条件,否则它将无限地调用自身。递归函数通常用于将一个大的问题分解成较小的子问题。在二叉树、图等数据结构以及二分查找、快速排序等算法中,经常会用到递归函数。

递归函数并非一开始就清晰易懂。如果你理解以下内容,你将更快地阅读和理解递归函数。首先,你应该始终确定函数的基准情况。向函数发送参数,以便它可以直接到达基准情况。确定哪些输入至少会调用一次递归函数。

阅读和编写递归函数几乎相同。创建一个可以通过其参数访问的、具有基准情况的普通函数。向函数提供参数,以便它可以直接调用基准情况。传递启动递归调用的后续参数。

让我们看看不同的方法来了解递归在JavaScript中的工作原理。

使用递归计算数字的阶乘

正数n的阶乘计算公式为:

n的阶乘 (n!) = 1 * 2 * 3 * 4 *... * n

负数的阶乘不存在。0的阶乘为1。

语法

以下是递归函数的语法:

function recursion() {
   if(condition) {
      recursion();
   } else {
      // stop calling recursion()
   }
}
recursion();

示例

在下面的示例中,我们将演示如何在JavaScript中使用递归查找数字的阶乘。我们创建一个名为fact()的函数,它带有一个参数“b”,该参数从主函数中获取值6。首先,我们检查该数字是否等于0。如果为真,则程序将返回1。在else语句中,我们将检查 b*fact(b-1),这大致相当于6*(6-1)。在下一个递归中,它将是5*(5-1),依此类推。这样,函数将继续计算数字的阶乘。在递归结束后,函数将打印出输入数字的阶乘值。

<html>
<head>
   <title> Factorial using Recursion </title>
</head>
<body>
   <h2> Factorial using JavaScript recursion </h2>
   <script>
      // program to find the factorial of a number
      function fact(b) {
         // if number is 0
         if (b === 0) {
            return 1;
         }
         // if number is positive
         else {
            return b * fact(b - 1);
         }
      }
      const n = 6;
      // calling factorial() if num is non-negative
      if (n > 0) {
         let res = fact(n);
         document.write(`The factorial of ${n} is ${res}`);
      }
   </script>
</body>
</html>

在上面的输出中,用户可以看到,在递归之后,我们发现该数字的阶乘为720。

循环递归

在这种技术中,我们将观察到一个函数1(a)调用函数2(b),函数2(b)调用函数3(c),函数3(c)调用函数1(a),形成一个循环。

示例

在下面的示例中,我们创建了三个函数来理解这种方法。首先,我们创建一个名为funA()的函数,它带有一个名为n的变量。我们检查这个值是否小于0,并执行某个操作(n-1)。这个函数调用funB()funB()在检查n是否大于2后执行某个操作(n-2)。然后funB()调用另一个函数funC(),该函数接受参数(n)。这就是嵌套递归的工作方式。

<html>
<body>
   <h2> Nested Recursion using JavaScript </h2>
   <script>
      // JavaScript program to show Cyclic Recursion
      function funA(n) {
         if (n > 0) {
            document.write(n.toFixed(0) + "</br>");
            // Fun(A) is calling fun(B)
            funB(n - 1);
         }
      }
      function funB(n) {
         if (n > 1) {
            document.write(n.toFixed(0) + "</br>");
            // Fun(B) is calling fun(C)
            funC(n - 2);
         }
      }
      function funC(n) {
         if (n > 1) {
            document.write(n.toFixed(0) + "</br>");
            // Fun(C) is calling fun(A)
            funA(n);
         }
      }
      funA(5);
   </script>
</body>
</html>

用户可以观察到,给funA()的第一个值为5。然后执行(n-1)得到4。(n-2)得到2。类似地,(n)得到2。然后得到(n-1)为1,传递给funB()。

嵌套递归

在这个递归中,参数将作为递归调用被递归函数发送。“递归中的递归”就是这个意思。为了理解这个递归,让我们看一个例子。

语法

func(n)
{
   Return func(func(n-1))
}

参数

  • n − 用于在嵌套递归中执行任何计算的参数。

示例

在这个例子中,我们创建了一个名为fun()的函数,它从驱动程序中获取一个名为**num**的值。这里我们创建了一个名为nested的函数,它接受一个整数参数。在这个函数内部有一个if-else块,它检查**num**是否> 100,如果是则返回**num**- 10,否则返回nested (nested (**num** + 11))。

<html>
<body>
   <h3> JavaScript program to show Nested Recursion </h3>
   <script>
      function fun(num){ 
         // A recursive function passing parameter
         // as a recursive call or recursion
         // inside the recursion
         if (num > 100)
            return (num - 10);
         else
            return fun(fun(num + 11));
      }
      var r;
      r = fun(98);
      document.write(r);
   </script>
</body>
</html>

输出显示了如何将98作为num递归调用,最终得到91的值。

结论

这三种方法阐明了执行递归的不同方法。第一种方法是一种简单的方法,帮助用户计算数字的阶乘。第二种方法帮助用户了解如何使用循环递归技术使用三个函数执行递归。第三种方法展示了嵌套递归如何在JavaScript中发生。

更新于:2022年7月22日

568 次浏览

启动你的职业生涯

通过完成课程获得认证

开始学习
广告