递归函数

34 阅读2分钟

递归执行过程分析

以 sum(5) 为例:

text

sum(5) = sum(4) + 5
sum(4) = sum(3) + 4  
sum(3) = sum(2) + 3
sum(2) = sum(1) + 2
sum(1) = 1  ← 基准情况

然后逐层返回:
sum(2) = 1 + 2 = 3
sum(3) = 3 + 3 = 6
sum(4) = 6 + 4 = 10
sum(5) = 10 + 5 = 15

递归函数的两个关键要素

1. 基准情况(Base Case)

scala

if (n == 1) {
    1  // 停止递归的条件
}

2. 递归情况(Recursive Case)

scala

else {
    sum(n - 1) + n  // 问题规模减小
}
object Main {
 def sum(n: Int): Int = {
        if (n == 1) {
            1  // 基准情况:当n=1时,返回1
        } else {
            sum(n - 1) + n  // 递归情况:前n-1项的和 + n
        }
    }

    def main(args: Array[String]): Unit = {
        val s = sum(100)
        println(s)  // 输出:5050
    }
}

1. 什么是递归函数?

递归函数是一种在函数体内直接或间接调用自身的函数。

它通常包含两个关键部分:

  1. 递归基(基准情形)
    这是递归的终止条件。当满足这个条件时,函数不再调用自身,而是返回一个确定的值,防止无限递归。
  2. 递归步骤
    在这一步中,函数调用自身,但通常以更小或更简单的问题规模进行,使得问题逐渐向递归基靠近。

示例(计算阶乘 n!n!):

python

def factorial(n):
    if n == 0:  # 递归基
        return 1
    else:       # 递归步骤
        return n * factorial(n - 1)

2. 递归函数适合用来解决一类什么样的问题?

递归特别适合解决具有以下特征的问题:

  1. 问题可以分解为规模更小的同类子问题
    例如:斐波那契数列、汉诺塔、二叉树遍历。
  2. 子问题的解可以合并成原问题的解
    例如:归并排序、快速排序。
  3. 存在明显的递归结束条件(递归基)
    例如:链表或树的遍历中遇到空节点时停止。
  4. 问题的定义本身是递归的
    例如:数学中的阶乘、斐波那契数列;计算机中的文件目录遍历(目录包含子目录)。

常见递归应用场景

  • 数学计算:阶乘、斐波那契数列
  • 数据结构遍历:树(前序、中序、后序遍历)、图(深度优先搜索)
  • 分治算法:归并排序、快速排序
  • 回溯算法:八皇后问题、迷宫求解
  • 动态规划:许多动态规划问题可以用递归+记忆化实现