递归:汉诺塔

一、递归的思想

  1. 递归分为递推和回归两个过程
    以求一个数n的n!为例:
    递推:若路人A能帮我把(n-1)!求出来,那我只需要在此基础上乘n就行了 路人A会想,若路人B能帮我把(n-2)!求出来,那我只需要在此基础上乘(n-1)就行了。
    照这样执行下去,总有一个人的工作是只需要把1!求出来就行了,那这个非常简单,我们定义一下1!=1就可以了。
    回归:当有人把1!=1算出来之后,就要开始算2!了,然后开始3!,知道n!,这个过程就称为回归。

  2. 递归不能无休止地执行下去,要有一个结束的标志
    如:
 def recursion():
     recursion()

        这种递归是毫无意义的,因为缺少递归完成的条件。等编译器执行到设置最大递归次数后就会出现异常。

        在上一个例子中,定义1!=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')

注意代码中的第一步第三步均使用自身定义的函数完成。

执行效果展示如下:


猜你喜欢

转载自blog.csdn.net/sinat_38486449/article/details/79733897