递归函数入门:以阶乘和斐波那契数列为例

自己调用自己的函数,看似绕晕,却是解决很多问题的利器。

👋 你好,我是 Evan ,一名计算机专业的学长,也是《大一突围》专栏的作者。刚学递归时,我对着 factorial(n) 看了半天,死活想不通"函数为什么能调用自身"。直到画了几次调用栈,才豁然开朗。今天我就用阶乘和斐波那契数列这两个经典例子,带你彻底搞懂递归------不只是语法,更是背后的思维模型。

欢迎来到 《大一突围》 专栏。

一、什么是递归?

递归就是函数在定义中调用自身。它把一个复杂问题分解成规模更小的子问题,直到达到最简单的"基准条件"。

递归的两个核心要素

  • 基准条件(base case) :不再递归,直接返回结果。例如阶乘中 0! = 1

  • 递归条件(recursive case):将问题缩小,调用自身。

调用栈可视化

当你调用 factorial(3) 时,栈的变化如下:

二、案例一:阶乘(factorial)

数学定义:

  • 0! = 1

  • n! = n × (n-1)!

2.1 Python 实现

python 复制代码
def factorial(n):
    # 基准条件
    if n == 0:
        return 1
    # 递归条件
    return n * factorial(n - 1)

print(factorial(5))  # 输出 120

2.2 Java 实现

java 复制代码
public class Factorial {
    public static int factorial(int n) {
        if (n == 0) return 1;
        return n * factorial(n - 1);
    }
    public static void main(String[] args) {
        System.out.println(factorial(5)); // 120
    }
}

2.3 执行过程(n=3)

  1. factorial(3) → 3 × factorial(2)

  2. factorial(2) → 2 × factorial(1)

  3. factorial(1) → 1 × factorial(0)

  4. factorial(0) → 1

  5. 返回:1 ← 1×1 ← 2×1 ← 3×2 = 6

三、案例二:斐波那契数列

数学定义:

  • F(0) = 0, F(1) = 1

  • F(n) = F(n-1) + F(n-2)

3.1 朴素递归实现

python 复制代码
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

print(fib(10))  # 55

3.2 调用树(n=5)

可以看到 fib(2) 被重复计算多次,导致指数级时间复杂度 O(2^n)。

四、递归优化:记忆化(Memoization)

用字典或数组缓存已经计算过的值,避免重复递归。

4.1 Python 记忆化

python 复制代码
python

def fib_memo(n, memo={}):
    if n in memo:
        return memo[n]
    if n <= 1:
        return n
    memo[n] = fib_memo(n-1, memo) + fib_memo(n-2, memo)
    return memo[n]

print(fib_memo(50))  # 瞬间出结果

4.2 Java 使用数组缓存

python 复制代码
java

public class Fibonacci {
    private static long[] memo;
    public static long fib(int n) {
        if (n <= 1) return n;
        if (memo[n] != 0) return memo[n];
        memo[n] = fib(n-1) + fib(n-2);
        return memo[n];
    }
    public static void main(String[] args) {
        memo = new long[51];
        System.out.println(fib(50));
    }
}

优化后时间复杂度:O(n),空间复杂度 O(n)。

五、递归 vs 迭代(循环)

阶乘的迭代实现

python 复制代码
python

def factorial_iter(n):
    result = 1
    for i in range(1, n+1):
        result *= i
    return result

斐波那契的迭代实现

python 复制代码
python

def fib_iter(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

六、常见递归陷阱与解决方案

七、总结与思考

  • 递归的本质:把大问题拆成同类型的小问题,直到可以直接解决。

  • 何时使用递归:问题天然具有递归结构(如树遍历、汉诺塔、快速排序)。

  • 何时避免递归:深度大、性能敏感、语言栈限制严(如 Python)。

递归就像俄罗斯套娃,最大的娃娃里装着稍小的,最小的不能再拆了,然后一个个打开,得到最终答案。

❓ 问题:你第一次理解递归时用的是什么例子?或者你在写递归时遇到过栈溢出吗?有没有什么妙招?欢迎在评论区分享,我会选出 3 位同学,送出《递归算法经典题目集锦》和《记忆化模板代码》。

📌 如果本文帮你打通了递归的任督二脉,请点 👍 赞 + 关注 ,本专栏 《大一突围》 持续输出编程基础与思维干货。

收藏本文,下次遇到递归题回来复习,画调用栈永远不过时。

相关推荐
AI行业学习2 小时前
CC‑Switch v3.16.1 免费下载(Windows+macOS+Linux)、使用方法【2026.6.11】
linux·开发语言·windows·python·macos·前端框架·html
DFT计算杂谈2 小时前
WannierTools输入文件wt.in一键批量生成脚本
java·前端·chrome·python·算法·conda
weixin_468466852 小时前
网络数据采集新手入门指南
python·网络爬虫·conda·编程
叫我:松哥2 小时前
基于卷积神经网络的人脸情绪识别算法,引入残差连接与SE注意力模块
人工智能·深度学习·神经网络·算法·cnn·迁移学习·图像识别
m沐沐2 小时前
【计算机视觉】OpenCV 模板匹配银行卡数字识别---上
人工智能·后端·python·opencv·计算机视觉·pycharm·numpy
deephub2 小时前
2026 年开源 Agent 工具包选型指南:延迟、审计、可移植性与语言栈
人工智能·python·大语言模型·多智能体
ellenwan20262 小时前
期货量化尾盘没清仓:天勤 trading_time 过滤与收盘前平仓
python·区块链
AI_零食2 小时前
HarmonyOS ArkTS 设计系统构建实战指南
学习·华为·harmonyos·鸿蒙·鸿蒙系统
数智工坊2 小时前
周志华《Machine Learning》学习笔记--第十五章--规则学习
笔记·学习·机器学习