递归执行过程分析
以 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. 什么是递归函数?
递归函数是一种在函数体内直接或间接调用自身的函数。
它通常包含两个关键部分:
- 递归基(基准情形)
这是递归的终止条件。当满足这个条件时,函数不再调用自身,而是返回一个确定的值,防止无限递归。 - 递归步骤
在这一步中,函数调用自身,但通常以更小或更简单的问题规模进行,使得问题逐渐向递归基靠近。
示例(计算阶乘 n!n!):
python
def factorial(n):
if n == 0: # 递归基
return 1
else: # 递归步骤
return n * factorial(n - 1)
2. 递归函数适合用来解决一类什么样的问题?
递归特别适合解决具有以下特征的问题:
- 问题可以分解为规模更小的同类子问题
例如:斐波那契数列、汉诺塔、二叉树遍历。 - 子问题的解可以合并成原问题的解
例如:归并排序、快速排序。 - 存在明显的递归结束条件(递归基)
例如:链表或树的遍历中遇到空节点时停止。 - 问题的定义本身是递归的
例如:数学中的阶乘、斐波那契数列;计算机中的文件目录遍历(目录包含子目录)。
常见递归应用场景
- 数学计算:阶乘、斐波那契数列
- 数据结构遍历:树(前序、中序、后序遍历)、图(深度优先搜索)
- 分治算法:归并排序、快速排序
- 回溯算法:八皇后问题、迷宫求解
- 动态规划:许多动态规划问题可以用递归+记忆化实现