Python中的递归详解
一、什么是递归?一句话讲清核心
递归的本质,是函数自己调用自己,并通过缩小问题规模,最终用小规模问题的解推导出原问题的解。
简单来说,递归就是把一个复杂问题,拆成和原问题逻辑相同但规模更小的子问题,直到子问题简单到可以直接得出答案(这个直接得出答案的条件就是递归出口),再层层回溯,得到原问题的解。
比如生活中最经典的“拆俄罗斯套娃”:要打开最外层的套娃,需要先打开内层的套娃,直到打开最里层的小娃娃(递归出口),再层层回退,最终打开所有套娃——这就是递归的核心思想。
在Python中,递归函数的结构只有两个核心部分,缺一不可:
1. 递归出口:终止函数自我调用的条件,避免无限循环(Python有递归深度限制,无限递归会直接报错);
2. 递归调用:函数自身调用,且每次调用都要让问题规模变小,向递归出口靠近。
二、递归的第一个实战案例:求n的阶乘
阶乘是递归的入门经典案例,适合快速理解递归的结构和执行过程。
阶乘的定义
n的阶乘(记为n!):n! = n × (n-1) × (n-2) × ... × 1,且1! = 1,0! = 1(递归出口)。
递归实现代码
def factorial(n):
# 递归出口:0!和1!的结果都是1
if n == 0 or n == 1:
return 1
# 递归调用:n! = n × (n-1)!,问题规模从n缩小到n-1
return n * factorial(n-1)
执行过程拆解
计算 factorial(5) 的过程,就是层层调用、层层回溯的过程:
plaintext
factorial(5) → 5 × factorial(4)
factorial(4) → 4 × factorial(3)
factorial(3) → 3 × factorial(2)
factorial(2) → 2 × factorial(1)
factorial(1) → 1(递归出口)
# 开始回溯计算
2×1=2 → 3×2=6 → 4×6=24 →5×24=120
这段代码完美契合递归的两大核心:有明确的出口,每次调用都缩小了问题规模。