递归剖析
两个过程
递“去”的过程,“归”回的过程!
def di_gui(n):
print(n, "<===1====>")
if n > 0:
di_gui(n - 1)
print(n, '<===2====>')
di_gui(5) # 外部调用后打印的结果是?
执行“去”的过程
- 只需要满足终止条件,就会一直在函数内,带着更新的参数,调用函数自身
【注:】到内部调用函数, 以下面的代码不会被执行,而是暂停阻塞;此时 随着函数每调用一次自身,还没有触发 返回值和到达终止条件,等同于在原来的基础上不断“向下/向内”开辟新的内存空间,
“递”去的过程结束
- 当前这层空间函数全部执行结束(终止条件)
- 执行到了return 返回值,直接返回;
从内存角度(本质):
每调用一次函数,都会单独开辟一份栈帧空间,递归函数就是不停的开辟和释放栈帧空间的过程,具体来理解下:一个普通函数从执行到结束,就是一个开辟空间和释放空间的过程;而递归函数是在调用最外层函数时,先开辟一个最外层空间,每调用一次自身,就会在最外层空间内,再自己开辟本次的空间(所以递归耗内存)
递归的数据共享情况:递归每一层间的数据是独立的,不共享,但是可以通过参数或者返回值来形成共享,参数具体在传入的是“引用类型”(比如列表)
【注:】递归 必须要有一个出口,如果没有出口就会重复调用,不断的开辟栈帧空间
import sys
res=sys.getrecursionlimit()
print(res) # 结果:1000
# sys.setrecursionlimit(800) 可以自己设置最大递归层数
return的返回流程是:先计算,再返回
def jie_cheng(n):
if n <= 1:
return 1
return n * jie_cheng(n - 1)
print(jie_cheng(5))
字符串的反转
def str_reverse(s):
if len(s) <= 1: # 递归出口
return s
return str_reverse(s[1:]) + s[0] # 每次返回最后一层的值,加上当前规模的第一个值
print(str_reverse('str'))
递归思路
- 找重复:看哪一部分是 实现函数的变化;每次进入更深一层递归时,问题规模相比上次递归都应有所减少
- 找变化:变化的量应该作为参数
- 找边界(出口):终止条件
需求:递归实现遍历目录
import os
def file_get(file_path, n):
list_file = os.listdir(file_path)
for file in list_file:
abs_file = os.path.join(file_path, file)
if os.path.isdir(abs_file):
print("\t" * n, file)
file_get(abs_file, n + 1)
else:
print("\t" * n, file)
file_get(r"C:\Users\DELL\Desktop\python", 1)