递归和迭代的区别是什么?
一、基本定义
- 递归:函数自己调用自己,依靠调用栈保存每一层状态
# 递归求阶乘 def fact(n): if n <= 1: return 1 return n * fact(n - 1) - 迭代(循环):使用
for / while,重复执行代码,靠变量保存状态# 迭代求阶乘 def fact_iter(n): res = 1 for i in range(2, n+1): res *= i return res
二、核心区别一览表
| 对比项 | 递归(Recursion) | 迭代(Iteration) |
|---|---|---|
| 实现方式 | 函数内部调用自身 | while / for 循环,不调用自己 |
| 状态保存 | 由程序调用栈自动保存每层参数 | 手动用变量记录状态 |
| 终止条件 | 基线条件(递归出口if) | 循环条件 |
| 内存开销 | 较大。每一次调用压入栈,层数多会栈溢出 | 小,仅几个变量,占用固定内存 |
| 代码风格 | 简洁优雅,贴近数学公式 | 代码稍长,逻辑直观 |
| Python限制 | 默认递归深度≈1000,深度大会RecursionError |
几乎没有层数限制 |
| 可读性 | 树结构、分治问题(目录遍历、快排)更好读 | 单纯重复计算(累加、累乘)更好读 |
三、执行原理形象理解
递归
任务不断拆分,先层层往下调用,触达出口后再逐层回溯计算
fact(5) → 5 * fact(4) → 4 * fact(3) ……直到 fact(1)=1,再反向算出结果。
所有中间结果压在栈里,等待后续运算。
迭代
从头开始一步步向前推进,不需要保存历史多层状态,只保留当前结果。
res初始=1 → res=1×2 → res×3 → res×4 → res×5,一路向前。
四、优缺点总结
✅ 递归优点
- 问题天然可以拆分(树形、分治)时代码非常简短
- 数学递归公式直接翻译成代码(阶乘、二叉树)
❌ 递归缺点
- 栈开销大;Python不支持尾递归优化
- 深度过大直接报错;重复计算(朴素斐波那契)效率极低
✅ 迭代优点
- 内存占用低,运行更快
- 没有递归深度限制,适合大规模循环
❌ 迭代缺点
- 复杂分治、树形遍历手动写栈会很繁琐
- 有些递归问题转迭代需要自己模拟栈
五、重要结论
- 所有递归都能改成迭代(手动用列表模拟调用栈);所有迭代也能改成递归。二者等价。
- 什么时候选递归?
文件递归遍历目录、二叉树遍历、分治算法(快速排序)。 - 什么时候优先迭代?
累加、累乘、大量重复运算,n数值很大时,尽量用循环,避免递归栈溢出。
六、同一个需求两种写法对照(1~n求和)
# 递归版本
def sum_rec(n):
if n == 1:
return 1
return n + sum_rec(n - 1)
# 迭代版本
def sum_iter(n):
total = 0
for i in range(1, n+1):
total += i
return total
新手容易踩坑提醒
很多人以为递归“高级”,一上来就乱用!
比如求第100项斐波那契,直接写递归会大量重复计算,极慢;换成循环轻松解决。

浙公网安备 33010602011771号