python——递归函数
递归函数
1. 递归函数的定义:函数直接或间接的调用函数本身,则称该函数为递归函数。也就是说,如果在一个函数内部,调用自身本身,那么这个函数就称为递归函数。
2. 计算阶乘的算法就用到了递归函数,func(n)= n * func(n-1)
1 #定义函数
2 >>> def func(n):
3 if n==1:
4 return 1
5 return n*func(n-1)
6
7 #调用函数
8 >>> func(1)
9 1
10 >>> func(5)
11 120
12 >>> func(100)
13 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
3. 递归函数的优点是逻辑简单清晰,缺点是过深的递归容易导致栈溢出
4. 尾递归:为了解决递归调用栈溢出的问题。尾递归是指,在函数返回的时候,调用自身,并且 return 语句中不能包含表达式。
尾递归和循环的效果一样,可以把循环看成一种特殊的尾递归函数。
用尾递归实现阶乘算法:
1 >>> def func(n):
2 return func_iter(n,1)
3
4 >>> def func_iter(num,product):
5 if num==1:
6 return product
7 return func_iter(num-1,num*product)
尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。
遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的 func(n)函数改成尾递归方式,也会导致栈溢出
5.汉诺塔问题:
1 >>> def move(n,a,b,c): #n为圆盘数,a代表初始位圆柱,b代表过渡位圆柱,c代表目标位圆柱
2 if n==1:
3 print(a,'-->',c)
4 else:
5 #将初始位的n-1个圆盘移动到过渡位,此时初始位为a,上一级函数的过渡位b即为本级的目标位,上级的目标位c为本级的过渡位
6 move(n-1,a,c,b)
7 print(a,'-->',c)
8 #将过渡位的n-1个圆盘移动到目标位,此时初始位为b,上一级函数的目标位c即为本级的目标位,上级的初始位a为本级的过渡位
9 move(n-1,b,a,c)
10
11
12 >>> move(3,'A','B','C')
13 A --> C
14 A --> B
15 C --> B
16 A --> C
17 B --> A
18 B --> C
19 A --> C