JavaScript 中的现实生活递归

17 Mar 2025 | 5 分钟阅读

在接触不同的编程语言时,我们都听过或学过递归的概念。在 JavaScript 中,我们也存在递归的概念,即我们使用递归函数。

因此,在本节中,我们将学习递归,并会看到一些递归的实际应用。我们还将讨论何时应使用递归以及何时应避免使用它。

什么是递归和递归函数

递归只是函数对其自身的递归调用,即函数在其自身内部进行递归调用。这种类型的函数称为递归函数,这种方法称为递归。通过递归,我们可以用优雅的解决方案解决许多复杂的问题。但是,建议我们避免使用递归,因为如果我们滥用它,可能会对系统及其存储的数据造成危险。此外,JavaScript 函数式编码风格不支持它,并且一些编译器无法安全地处理递归函数。

递归函数的语法如下所示

应该注意的是,递归函数必须有一个停止执行的条件;否则,函数将无限次地被调用和执行。

何时使用递归

递归能够将大型复杂问题分解为小型问题。但是,并非所有复杂问题都可以通过递归解决。对于迭代分支等问题,如排序、遍历、二分查找以及其他数据结构,使用递归函数是最合适和有效的。此外,当需要在循环中反复调用同一个函数但使用不同的参数值时,使用递归函数是很好的。例如,使用递归查找数字(一个大数)的阶乘、斐波那契数列的实现、汉诺塔问题都可以通过递归轻松解决。

何时避免使用递归

如果问题太小,只需要几行简单的代码就可以解决,那么就应该避免使用递归来解决。这是因为递归函数会不断调用自身,直到停止。因此,它会不必要地占用大量内存。因此,当我们解决一个可以不使用递归就能解决的问题时,请避免使用它。有时,可能会出现滥用递归导致整个程序陷入无限循环,除了终止程序别无他法的情况。所以,请在需要且正确使用递归的地方使用。

实现递归的实际应用示例

通常,递归是面试官喜欢的话题,因为他们经常会问与递归相关的问题。在我们的实际生活中,有很多递归的应用

示例 1:搜索算法

我们学过的许多搜索算法都使用了递归,例如二分查找。因此,下面的代码展示了递归在二分查找中的应用

输出

JavaScript Recursion in Real Life

也有另一种不使用递归的方法来解决二分查找,但遍历整个数组来查找元素既复杂又耗时。因此,使用递归可以简化这个问题。

示例 2:延迟计时器

如果我们想在设定的时间段后多次执行某个函数,那么使用递归是最好的选择。所以,让我们来看看它的代码实现

输出

JavaScript Recursion in Real Life

在上面的代码中,

  • 我们设置了一个延迟计时器,因此数组中的元素将在几秒钟后打印到屏幕上,如输出快照所示。
  • 同样,这个过程将一直持续到最后一个值。
  • 您还可以注意到我们在这里使用了递归,并且该函数一直调用自身,直到 if 条件变为 false。

示例 3:谜题求解

选择递归来解决谜题是最佳选择,因为递归可以帮助获得谜题的最佳优化解决方案。我们在日常生活中可能会玩很多谜题,比如井字棋。如果我们尝试使用迭代解决方案,就会知道这有多么困难,因为对于每一步,我们需要考虑许多因素——这是一个复杂的问题。但是,通过递归算法可以轻松或不那么复杂地找到最佳的移动方式。因此,不仅对于井字棋,而且对于那些您知道有多个迭代移动且需要确定最佳移动的游戏,递归都是最佳方法。

示例 4:分形设计

我们可以使用递归来解决分形设计。分形设计/图案是递归定义的设计。这些分形设计看起来像

JavaScript Recursion in Real Life

该图案包含许多复杂的步骤,难以解决。但是,当我们尝试使用递归方法解决分形设计时,我们可以判断和查看每个特定步骤的输出。

示例 5:归纳证明

归纳证明是基本情况和归纳步骤的组合,其中

  • 基本情况是可以对某个特定值(P(0))证明为真的情况。
  • 归纳步骤表示我们可以从 P(n) 得到 P(n+1)。

例如:爬楼梯

JavaScript Recursion in Real Life
  • 这个例子中的基本情况是“我们能爬到楼梯的第一个台阶吗?”
  • 这里的归纳步骤是“我们能否从一个台阶到下一个台阶,目标是楼梯上的任意台阶?”答案是肯定的,当我们假设楼梯是完美且无限长的时,我们可以从一个台阶到另一个台阶。然而,现实世界中存在局限性。这是因为楼梯可能不一定是完美的,即它可能不是无限高的,而且台阶可能缺失或不均匀。但我们将其视为一个完美的楼梯。因此,通过这两个组成部分,已经证明我们可以从地面爬到楼梯上的任何台阶。

同样,还有更多可以使用递归解决的归纳证明的例子。

因此,以上这些都是递归的实际应用以及我们使用递归的例子。


下一个主题JavaScript removeChild