- 递归函数(自调用函数),在函数体内部直接或间接地自己调用自己。
两个必要条件:
1、结束条件,边界条件
2、递归步骤,从一般到特殊情况的转换
例1、阶乘函数
def factorial(n):
if n==1: # 结束条件
return 1
return n*factorial(n-1) # 递归步骤
# 示例
for i in range(1,10): #计算从1-9的阶乘
print(i,'!=',factorial(i))
例2、调和数(1+1/2+1/3+…+1/n)
def harmonic(n):
if n==1:
return 1
return harmonic(n-1)+(1/n)
for i in range(1,10):
print(i,'!=',harmonic(i))
例3、汉诺塔:
三根柱子,第一根柱子上从下往上按照大小顺序摞着n片圆盘,按大小顺序重新摆放在另一根柱子上,并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
汉诺塔问题的解决方案通常使用递归方法来实现。对于n个盘子,解决方案可以分解为以下步骤:
- 将上面的n-1个盘子从起始柱子移动到辅助柱子上(使用目标柱子作为辅助)。
- 将剩下的最大的盘子移动到目标柱子上。
- 将那n-1个盘子从辅助柱子移动到目标柱子上(这次使用起始柱子作为辅助)。
下面的代码呈现了n个圆盘按照上述的方法移动的过程:
def hanoi(n, source, target, auxiliary):
"""
参数解释
n: 盘子的数量
source: 起始柱子
target: 目标柱子
auxiliary: 辅助柱子
"""
if n == 1:
# 如果只有一个盘子,直接移动到目标柱子
print(f"Move disk 1 from {source} to {target}")
return
# 第一步:将n-1个盘子从source移动到auxiliary
hanoi(n-1, source, auxiliary, target)
# 第二步:将剩下的盘子第n个盘子 从source移动到target
print(f"Move disk {n} from {source} to {target}")
# 第三步:将n-1个盘子从auxiliary移动到target
hanoi(n-1, auxiliary, target, source)
#递归调用,注意n-1个盘子的移动与n个盘子的移动,起始柱子和辅助柱子交换。
#示例,移动3个盘子
hanoi(3, 'A', 'C', 'B')
#输出结果
#Move disk 1 from A to C
#Move disk 2 from A to B
#Move disk 1 from C to B
#Move disk 3 from A to C
#Move disk 1 from B to A
#Move disk 2 from B to C
#Move disk 1 from A to C
例4、最大公约数(Greatest Common Divisor, GCD)
def gcd(a, b): #a>b
if b == 0:
return a
else:
return gcd(b, a % b)
# 示例
num1 = 48
num2 = 18
print(f"The GCD of {num1} and {num2} is {gcd(num1, num2)}")
#输出The GCD of 48 and 18 is 6
注:3.5以上版本中math模块,gcd函数可以直接求两个数的最大公约数。math.gcd(num1, num2)