汉诺塔算法
汉诺塔是指,有三根棍子,在a棍子上串有从小到大依次排放的圆片,怎样移动能够使得将这些原片从a转移动c,且移动过程中始终是小圆片放在大圆片上方
def hnt(n,a,b,c):
if n==1:
print(‘a–c’)
else:
hnt(n-1,a,c,b)
print(‘a-c’)
hnt(n-1,b,a,c)
思想是,如果有n个圆片,n>1,那个首先要做的是把这上面的n-1个圆片从a先移动到b,然后把第n个圆片从a移动到c,再把b上的n-1个圆片从b移动到c。而把n-1个圆片从a移动到b和从b移动到c,这本身也是一个汉诺塔问题,因此可以直接调用本函数,这也就是递归思想。
我又进一步进行了思考,如果要计算出总共用的步数该怎么搞,刚开始的想法是,增加一个d=0作为默认参数,然后没进行一步,就更新d,如下代码所示:
def hnt(n,a,b,c,d=0):
if n==1:
print(a,’–’,c)
d=d+1
else:
hnt(n-1,a,c,b,d)
print(a,’–’,c)
d=d+1
hnt(n-1,b,a,c,d)
return
hnt(3,a,b,c)
但是这样运行确报错了,错误的原因在于,在else这个分支之中,d返回的值还是1,加过之后的d并不能作为下一个参数去运行hnt(n-1,b,a,c,d),也就是说他不能叠加。对于递归函数而言,必须给出明确的递归结果,这个结果应该是一个递推公式
def hnt(n,a,b,c,d=0):
if n==1:
print(a,’–’,c)
d=d+1
else:
hnt(n-1,a,c,b,d)
print(a,’–’,c)
hnt(n-1,b,a,c,d)
d= hnt(n-1,a,c,b,d)+ hnt(n-1,b,a,c,d)+1
return d
print(hnt(3,a,b,c))
因此,我做了改动,改成递推公式后发现,对于递推公式,它也会打印每一个hnt里面的步骤,而这对于计算来说是不正确的所以,只能单独的写一个公式
def hnt(n,a,b,c,d=0):
if n==1:
d=1
else:
d= 2*hnt(n-1,b,a,c,d)+1
return d
print(hnt(3,a,b,c))
因为处于初学阶段,我还没有很好的办法消除这两个同时应该如何出现,这里挖一个坑,希望以后能够解决
来源:CSDN
作者:chaoren1128
链接:https://blog.csdn.net/chaoren1128/article/details/103875306