一、函数递归 recursion
什么是递归:
函数直接或者间接的调用自身
示例:直接调用自身------死递归
def f():
f()
f()
print("递归完成")
执行结果:
RecursionError: maximum recursion depth exceeded
示例:间接调用自身------死递归
def fa():
fb()
def fb():
fa()
fa()
执行结果:
RecursionError: maximum recursion depth exceeded
递归说明:
递归一定要控制递归层数,当符合某一条件时要终止递归
几乎所有的递归都能用循环来代替(重复的做一些事,规则相同,可用递归)
递归的优缺点:
优点:
递归可以把问题简化,让路径更为清晰,代码更为简洁
缺点:
递归因系统环境影响大,当递归深度太大时,可能出现使系统崩溃等不可预知的后果
def stroy():
print("从前有座山 :")
s = input("还想听吗: ")
if s == "不想听了烦死了":
print("故事讲完了 ")
else:
stroy()
stroy()
执行结果:
从前有座山 :
还想听吗: 1
从前有座山 :
还想听吗: 1
从前有座山 :
还想听吗: 1
从前有座山 :
还想听吗: 2
从前有座山 :
还想听吗: 不想听了烦死了
故事讲完了
举一个栗子并进行图解递归程序的执行:
def fn(n):
print("现在是第",n,"层递归")
if n >= 3:
return
fn(n+1)
print("递归的第",n,"层结束")
fn(1)
print("程序结束,回到主程序")
执行结果:
现在是第 1 层递归
现在是第 2 层递归
现在是第 3 层递归
递归的第 2 层结束
递归的第 1 层结束
程序结束,回到主程序
图解该递归执行的流程:
红色代表从递归入口到递归最深处
绿色代表从递归的最深处返回递归的调用点
二、如何实现一个递归函数: 先假设函数已经实现
示例:
用递归函数求和,求100+99+98+…+2+1
分析:
先假设mysum(x)已经完成,且能求x+(x-1)+…+1的和
def mysum(x):
#判断递归终止条件
if x == 1:
return 1
return x + mysum(x -1)
分析:
我们要从100一直加到1,可以看作是100和括号中
100 + (99+98+…+2+1) 即100 +mysum(99)
接下来:
99+(98+…+2+1) 即 99 + mysum(98)
…
以此类推:
mysum(x) = x + mysum(x - 1)
实现:
def mysum(x):
if x == 1:
return 1
return x + mysum(x - 1 )
print(mysum(100))
执行结果:
5050
三、练习:
1.编写函数,myfac(x)计算x的阶乘x!
def myfac(x):
if x < 2:
return 1
return x*myfac(x-1)
#2! = 2*myfac(1)
#3! = 3*myfac(3-1)
#4! = 4*myfac(4-1)
# .....
#n! = n*myfac(n-1)
print(myfac(3))
执行结果:
6
2.写程序算出1-20阶乘的和
1!+2!+…+19!+20!
考虑:
能否用函数式编程中的高阶函数实现?
def Facsum(n):
if n == 1:
return 2
if n == 0:
return 1
else:
return myfac(n)+Facsum(myfac(n-1))
#1!+2! = 2! + Facsum((2-1)! )
# 1!+2!+3! = 3! + Facsum((3-1)! )
# ....
#1!+2!+...+n! = n! + Facsum((n-1)!)
print(Facsum(3)) #这个数不要太大,如果递归的层次太深会崩溃掉
执行结果:
10
3.已知有列表:
L = [[3,5,8],10,[[13,14],15],18]
1)写出一个函数print_list(lst)打印出列表中所有数字
print_list(L)
2)写出一个函数sum_list(lst)返回列表中所有数字的和
print_list(sum_list(L))
注:
type(x) 可以返回一个变量的类型
1)
L = [[3,5,8],10,[[13,14],15],18]
def print_list(L):
for x in L:
if type(x) != list: #判断对应元素是一个列表还是数值,如果是数值直接打印
print(x,end=' ')
else: #否则调用print_list()递归的将对应列表内元素进行打印
print_list(x)
print_list(L)
执行结果:
3 5 8 10 13 14 15 18
2)
def sum_list(lst):
val = 0
for x in lst:
if type(x) != list:
val += x
else:
val+=sum_list(x)
return val
print(sum_list(L))
执行结果:
86