十、递归
递归的实现原理是在函数内部调用自身, 每次调用函数都需要做 压栈、 弹栈、 保存和恢复寄存器的栈操作。
所以是非常消耗时间和空间的。另外如果递归忘记返回(没有设置递归边界)就会完全消耗掉内存资源或者使程序崩溃。
递归的三要素:
1、明确递归终止条件; 【递归边界】
2、给出递归终止时的处理办法;
3、提取重复的逻辑,缩小问题规模。
def return_self():
print('我在调用自己')
return return_self()
return_self()
输出一百个 我在调用自己 然后抛出异常 : RecursionError: maximum recursion depth exceeded while calling a Python object
这个异常是 python 基于对内存的保护自动抛出的, 如果无限调用自己, 最终会将系统的内存消耗完, python 默认的递归深度为 100 层。
求阶乘 :
方法一、使用迭代
def factorial(n):
result = n
for i in range(1, n):
result *= i
return result
print(factorial(4)) 24
方法二、使用递归
def factorial(n):
if n == 1: 【递归边界】
return 1 【给出递归终止时的处理办法】
else:
return n * factorial(n - 1) 【提取重复的逻辑,缩小问题规模】
print(factorial(4)) 24
求斐波那契数列:
迭代 :
def fbnq2(n):
n1 = 1
n2 = 1
n3 = 1
if n < 1:
print('输入有误')
return -1
while n > 2:
n3 = n2 + n1
n1 = n2
n2 = n3
n -= 1
return n3
print(fbnq2(7)) 13
递归 :
def fbnq(n):
if n <= 2:
return 1
else:
return fbnq(n - 1) + fbnq(n - 2) 分治思想
print(fbnq(7)) 13
汉诺塔游戏 :
递归 :
def hanoi(n, x, y, z):
if n == 1:
# 将一个圆盘从 x 移动到 z
print(x,' --> ', z)
else:
# 将上面的 n-1 个圆盘从 x 移动到 y
hanoi(n-1, x, z, y)
# 将底部最后一个圆盘从 x 移动到 z
print(x, ' --> ', z)
# 将 y 上的 n-1 个圆盘移动到 z
hanoi(n-1, y, x, z)
hanoi(2, 'x', 'y', 'z')
输出 :
x --> y
x --> z
y --> z