|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
经过前两次的洗礼,对递归的感觉已经好了非常多,如果对递归逻辑有疑问的可以仔细看我前两个求助贴,里面有凌九霄大大的详细讲解。
然后,我给自己加了一题,汉诺塔。之前有人求助过,从一个菜鸟的理解来看,还是觉得不够清晰,所以我也把我的递归逻辑也写出来,希望能帮到其他新手。
n代表片数(片的大小对应数字的大小),a,b,c 分别代表三根柱子。
n=1,非常简单,a移到c
n=2,n-1从a移到b,n从a移到c,n-1从b移到c
n=3,n=2(n-1)从a移到b,n从a移到c,n=2(n-1)从b移到c
n=4,n=3(n-1)从a移到b,n从a移到c,n=3(n-1)从b移到c(只是为方便理解递归思路,理解思路的话可以不看)
n=1、2非常容易,不解释了;n=3、n=4,包括n=5678,n=100,很容易看出是在重复前面的第2步的做法,这就是递归思想,还不能理解可以看我前面的2次求助。
那我们来看,重复了哪些操作,就是我们要在递归函数里写的内容,主要就3步,不是大象放冰箱的3步。。。
第一步:把n-1(最底下一片上面的所有片)从a移到b;第二步,把第n片(最底下一片)移到c;第三步,把前面移到b上的所有n-1片移到c,完成!
这里有藏着一个理解上的小难点,很多新手在这里都会晕,可以看到n=2是被后面调用的基础,而且是在n=3的操作中调用了两次(当然n=45678,100也是两次),但是n=2实现的是把两片从a移到了c上,而n=3希望的两次调用,第一次(第一步)是从a移到b,第二次(第三步)是从b移到c,这样的话,我们只要把后面调用的参数换一下就可以了嘛,第一步:因为从a移到b,就把原来的c和b换一下嘛,原来是(a,b,c)换成(a,c,b);第三步:从b移到c,就把原来的b和a换一下,原来是(a,b,c)换成(b,a,c)。这里还要强调一点,n=2时是固定把a移到c,所以里面的a,b,c是不会变化的,别把自己搞晕了。
好了思路上大功告成了,我们把思路变成代码:
设定参数def hanoi(n片数,a第1柱, b第2柱,c第3柱)
如果 n=1
打印 a-->c
此外(代表n>1)的情况
第一步,把n-1片从a全部移到b 调用hanoi(n-1除了最低下1片的所有片同时代表下一次调用,下一次调用a第1柱起点不变,下一次调用c第3柱和第2柱互换后作为过渡柱,下一次调用b第2柱和第3柱交换变成目的柱)
第二步,把第n片1片,从a移到c,当次调用,当次调用,当次调用,重要的事情说三次,直接打印a-->c
第三步,再把n-1片从b全部移到c 调用hanoi(n-1除了最低下1片的所有片同时代表下一次调用的片数,下一次调用b把第2柱换成起点柱,下一次调用a第1柱和第2柱互换后作为过渡柱,下一次调用c目的柱不变)
好了,代码是这样的:
def hanoi(n,a,b,c):
if n==1:
print(a+'-->'+c)
else:
print(hanoi(n-1,a,c,b))
print(a+'-->'+c)
print(hanoi(n-1,b,a,c))
hanoi(3,'a','b','c')
运行出来是对的,但是很奇葩,我的问题也来了,和我上次的问题的有点点类似,return怎么写,函数不能反个空屁蛋出来吗?
请大大多帮助一下。
本帖最后由 凌九霄 于 2018-6-28 19:06 编辑
python里函数不一定要有return。另外,else后面的两个递归调用不需要print,因为本来也没有返回
|
|