递归函数
定义:调用一个函数的过程中出现调用函数本身,成为函数的递归调用。
例1:
某公司四个员工坐在一起,问第四个人薪水,他说比第三个人多1000,问第三个人薪水,第他说比第二个人多1000,问第二个人薪水,他说比第一个人多1000,最后第一人说自己每月5000,请问第四个人的薪水是多少?
要知道第四个人的月薪,就必须知道第三个人的,第三个人的又取决于第二个人的,第二个人的又取决于第一个人的,而且每一个员工都比前一个多一千,数学表达式即:
salary(4)=salary(3)+1000 salary(3)=salary(2)+1000 salary(2)=salary(1)+1000 salary(1)=5000 简化为: salary(n)=salary(n-1)+1000 (n>1) salary(1)=5000 (n=1)
其实,这就是一个递归函数,递归分为两个阶段:回溯和递推。
第n个员工的薪水表示为第(n-1)个学生的薪水,可第(n-1)个学生的薪水仍然不知道,所以继续回溯到第(n-2)个学生的薪水……直到第一个员工的薪水,此时,salary(1)已知不必再向前回溯了。然后开始第二个阶段:递推,从第一个员工的薪水可以推算出
第二个员工的薪水(6000),从第二个员工的薪水可以推算出第三个员工的薪水(7000)……一直推算出第第四个员工的薪水(8000)为止,递归结束。需要注意的一点是,递归一定要有一个结束条件,否则陷入无限死循环,这里salary(1)=5000就是结束条件。
流程图:
代码实现:
def salary(n): if n==1: return 5000 return salary(n-1)+1000 s=salary(4) print(s)
例2: 通过递归求n的阶乘
分析其数学表达式为:
(1)factorial(n)=n*factorial(n-1)
(2)factorial(1)=1
代码实现:
def factorial(n): if n==1: return 1 return n*factorial(n-1) print(factorial_new(3))
递归函数的优点: 定义简洁,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑处理会复杂一些。
递归特性:
-
必须有一个明确的结束条件
-
每次进入更深一层递归时,问题规模相比上次递归都应有所减少递归效率不高,递归层次过多会导致栈溢出(
-
在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返 回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
练习:通过循环和递归两种方式实现斐波那契数列


def fibo(n): before=0 after=1 for i in range(n-1): ret=before+after before=after after=ret return ret print(fibo(3)) #**************递归********************* def fibo_new(n):#n可以为零,数列有[0] if n <= 1: return n return(fibo_new(n-1) + fibo_new(n-2)) print(fibo_new(3)) 1 print(fibo_new(30000))#maximum recursion depth exceeded in comparison