一、递归的思想
- 递归分为递推和回归两个过程
以求一个数n的n!为例:
递推:若路人A能帮我把(n-1)!求出来,那我只需要在此基础上乘n就行了 路人A会想,若路人B能帮我把(n-2)!求出来,那我只需要在此基础上乘(n-1)就行了。
照这样执行下去,总有一个人的工作是只需要把1!求出来就行了,那这个非常简单,我们定义一下1!=1就可以了。
回归:当有人把1!=1算出来之后,就要开始算2!了,然后开始3!,知道n!,这个过程就称为回归。 - 递归不能无休止地执行下去,要有一个结束的标志
如:
def recursion(): recursion()
这种递归是毫无意义的,因为缺少递归完成的条件。等编译器执行到设置最大递归次数后就会出现异常。
在上一个例子中,定义1!=1就是递归完成的条件。
二、递归的几个例子
- 求数n的阶乘n!
首先在没有学习递归之前我们可以使用迭代的方法去完成,代码如下:
def fact(n): result = n for i in range(1,n): result *= i return result number = int(input('请输入一个数:')) result = fact(number) print("%d的阶乘为: %d"%(number,result))学习了递归可以使用递归方法,代码如下:
def fact_recursion(n): if n == 1: return 1 return n*fact_recursion(n-1) number = int(input('请输入一个数:')) result = fact_recursion(number) print("%d的阶乘为: %d"%(number,result)
2. 求菲波那切数列
注意在斐波那契数列中用到了两个自我调用,所以会需要两个初始值(或者称为完成条件),即:f(1)=f(2)=1
代码如下:
def febnaqie(n): if n == 1 or n == 2: return 1 return febnaqie(n-1)+febnaqie(n-2) for i in range(1,13): print(febnaqie(i))
实际上递归的实现时非常浪费时间的,当递归层数逐渐变大时,计算速度所需时间会变得很长,而迭代会非常省时:
def fibb(n): a,b = 0,1 for i in range(1,n+1): a,b =b,a+b #注意此处采用的这种赋值法,是先进行右边计算在进行赋值,不能用a = b 然后再b = a+b print(a)
fibb(12) 1 1 2 3 5 8 13 21 34 55 89 144
3. 求解汉诺塔问题
代码如下:
def hanoi(n,x,y,z):#x为起始位置(柱子),y为借用的柱子,z为目的位置 if n == 1: print(x,'-->',z)#结束的条件,也就是递推到最后一步时最后一个人做的工作 else: hanoi(n-1,x,z,y)#第一步,有人将n-1个圆盘从x借助z移动到y柱子上 print(x,'-->',z)#第二步,我将最后一个圆盘从x柱子移动到z柱子上 hanoi(n-1,y,x,z)#第三步,有人将n-1个圆盘从y柱子借助x柱子移动到z柱子上 hanoi(3,'x','y','z')
注意代码中的第一步第三步均使用自身定义的函数完成。
执行效果展示如下: