学习算法第四天(python)---递归

本文通过实例讲解了递归方法在计算阶乘和求解a的b次方中的应用,以及如何解决汉诺塔问题。重点介绍了递归的出口设定和问题分解策略,并展示了递归函数move(n,A,B,C)的实际运行过程。
摘要由CSDN通过智能技术生成

好久不见,递归法就是在函数中通过对自身函数的调用来求解特定结果,通常把一个大型的复杂问题,转化为与该复杂问题相似但规模更小的问题来求解。和递推相比,递归代码可读性更强

运用递归,主要需要考虑两个问题

①递归出口

②如何把一个复杂问题转化为多个简单问题

目录

1.求解n!(n的阶乘)

2.求解a的b次方

3.汉诺塔问题。


先来两道简单题热热身(●ˇ∀ˇ●)

1.求解n!(n的阶乘)

递归法:

a=int(input())
def F(a):
    if a<=1:
        return 1
    ans=a*F(a-1)
    return ans
print(F(a))

递推法:

a=int(input())
ans=1
for i in range(1,a):
    n=i+1
    ans=ans*n
print(ans)
2.求解a的b次方

递归法:

a=int(input())
b=int(input())
def F(a,b):
    if b==0:
        return 1
    elif b<0:
        return 1/a*F(a,-b)
    else:
        return a*F(a,b-1)
print(F(a,b))

递推法:

a=int(input())
b=int(input())
ans=1
for i in range(b):
    ans=ans*a
print(ans)

感觉到其中的奥妙了么?接下来这个问题会稍微复杂一些 

3.汉诺塔问题。

当下有n个大小不同的圆盘,由大到小放在一个柱子上,现要将这些圆盘移动到另一个柱子上,一次只能移动一个圆盘,移动期间只能大圆盘在下小圆盘在上。提供一根辅助柱子帮助移动(也就是一共n个圆盘,3个柱子),设三个柱子分别为A、B、C,显示圆盘的移动过程如A->B

 如图所示,我们可以把A看作所在柱子,C看作目标柱子,B为需要借助的柱子。因为整个过程只能大盘在下小盘在上的原则,要想把整个塔移动到C,一定是要先把最大盘上面的所有盘按从大到小的顺序放在B(A柱放现在最大盘,C柱子空着等待最大盘移入)。

若最大盘为n,其次大为n-1、然后n-2、n-3......1

那么我们接下来考虑的问题就是如何把n-1个盘子从A移动到B(n-1范围内的汉诺塔问题),那就需要包第n-1个盘子上面的所有盘按从大到小的顺序放在C(A柱放现在最大盘,B柱子空着等待最大盘移入),也就是把n-2 个盘子从A移动到C(n-2范围内的汉诺塔问题)......

所以,递归!

def move(n,A,B,C):
    #递归出口
    if n==0:
        return
    #先将n-1个盘子由大到小放在B上
    move(n-1,A,C,B)
    #将第n个盘子移动到C上
    print("{}->{}".format(A,C))
    #再将n-1个盘子由大到小放在C上)
    move(n-1,B,A,C)
move(4,"A","B","C")

运行结果:

这里展示的是n为4的情况怎么样,是不是和预想的盘子移动顺序一样。不知道有没有人好奇代码

    #将第n个盘子移动到C上
    print("{}->{}".format(A,C))

n的取值不同,第一个盘子要移动的位置也不同,为什么一定确定是A到C呢,哈哈,一定要记住这里的A和C都是形参而不是实参

定义函数move(n,A,B,C)中的A、B、C也都是形参,分别代表着圆盘的“初始位置”、“暂留位置”、“目的位置”,所以它是很灵活的,让我们来看一看计算机具体每一步是如何处理的吧

进入函数move(n,A,B,C),在第六行代码开始递归,逐步查找n=3、n=2、n=1时move(n,A,B,C)的值无果,

move(4,A,B,C)

move(3,"A","C","B")

move(2,"A","B","C")

move(1,"A","C","B")

来到n=0,触及退出判断,退出语句move(0,"A","C","B"),来到move(1,"A","C","B"),中,执行下一句打印语句,这时A="A",C="B"

打印A->B

打印完成后执行下一语句,此时n=1,所以下一句执行的是move(0,"C","A","B")

触及退出判断退出语句move(0,"B","A","C"),就此move(1,"A","C","B")完成,来到move(2,"A","B","C")中的下一个语句----打印,此时A="A",C="C",n=2

打印A->C

然后执行下一个语句move(1,"B","A","C"),进入该语句的函数中又遇见了move(0,"B","C","A")返回,执行下一个打印操作

接着遇见move(0,"A","B","C"),返回。move(2,"A","B","C")就此完成,来到move(3,"A","C","B")。

之后就是重复的动作了,感兴趣的可以自己试一试。(不得不说这么繁多的步骤,还是看递归式更直观些,重在理解)

今天先到这里,明天继续练习,明天见~

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值