用递归法求汉诺塔问题Python,汉诺塔递归算法编程
学习递归的时候有一个ajdnm练习。ajdnm应该是学习计算机递归算法的经典入门案例,所以我觉得可以写个博客来表达一下自己的观点。这个markdown编辑器不太会用。可能写的格式有点难看。请原谅我给你的高音响。
我在网上找到一张ajdnm的照片。ajdnm就是用中间的柱子把最左边柱子上的磁盘从大到小堆叠起来。说白了,C应该和原来的a一样。
废话少说,先闪码。
定义移动(n,a,buffer,c):
如果(n==1):
打印(a,-,c)
返回
移动(n-1,a,c,缓冲区)
移动(1,a,缓冲区,c)
移动(n-1,缓冲区,a,c)
移动(3, a , b , c )
首先定义一个移动函数,用四个参数表示A列的板数,buffer是b列,命名为buffer是为了方便理解,顾名思义就是从A到C的缓冲,那么C就是目标列。
让我们来读功能代码。
递归的一般写法必须有一个停止递归循环的条件,这样你就可以在判断A列的板数为1时停止递归返回。当A列上只有一个盘子时,您必须将A移动到C,重点是下面的代码。递归实际上是一种非常抽象的算法。我们要用抽象思维来思考ajdnm,把a柱上的板块想成两部分,即上盘和下盘,如图所示。
我们不在乎上面有多少个盘子。每次操作都是通过缓冲区B柱缓冲将底板移动到C柱。
童鞋们一定在想为什么要把酱紫搬走。其实这是一种总结。你自己玩ajdnm游戏就会发现其中的规律。这个游戏其实就是不断的尝试把上面的都移到B上,然后得到A到C的最后一个也是最大的一个,然后绞尽脑汁把B上的那个移到C上,这个时候你会发现B上原来的那个必须先通过空的那个,也就是A,把当前B上的n-1个存储起来,然后
让我们用刚才的抽象思维来解读剩下的代码。
移动(n-1,a,c,缓冲区)
这个代码的意思是,刚才提到的a柱上面的n-1位,会按照从小到大的规则,先被C移动到缓冲区。这个函数进入递归。
移动(1,a,缓冲区,c)
当执行上述语句时,也就是n-1块板的递归移动完成后,执行这条语句就是将A列上的一块板移动到C列,也就是所谓的底板。
移动(n-1,缓冲区,a,c)
最后一步是将A上的n-1全部移动到刚才的缓冲区。整个ajdnm可以通过A移动到C是肯定的,所以最后一步自然是通过A把刚才的n-1移动到C列作为缓冲。
我把整个搬家过程写下来,以a柱上的三个为例。
/**
我用代码演示了三个板块的所有ajdnm。根据缩进的原理,每次缩进都会进入一个递归函数,每次打印也就是每次打印都会停止当前的递归。
描述:
1.n=3,n=2,n=1是if(n==1)每次执行的结果,这里不写判断。相信童鞋也能理解,就是当n不等于1时,减1进入递归。
2.请注意A、B、C列每次进入函数的顺序。不要被形式参数误导,看每个函数参数的实际参数。
**/
移动(3, a , b , c )
n=3:
//从A开始移动n-1,即通过C移动2块板到B,为A的最后一块板移动腾出C。
移动(2, a , c , b )
n=2:
//从n=2开始递归,将当前a(a )列上的n-1个图板移动到b(c )到c(b )
移动(1, a , b , c )
n=1:
//完成n=2的第一次递归,打印结果,执行当前子函数的剩余代码。
打印( a ,-, c )
移动(1, a , c , b )
n=1:
打印( a ,-, b )
移动(1, c , a , b )
n=1:
打印( c ,-, b )
//这里a柱上面的n-1是2个板块的移动。
//开始将A列的最后一块板移到c列。
移动(1, a , b , c )
n=1:
打印( a ,-, c )
//到这里完成将A列的最后一个盘子移到c列。
移动(2, b , a , c )
n=2:
//开始n=2的第二次递归,即通过a(a )移动当前b(b )到c(c )的板块(n-1)
移动(1, b , c , a )
n=1:
//完成n=2的第二次递归,打印结果并执行当前子函数的剩余代码。
打印( b ,-, a )
移动(1, b , a , c )
n=1:
打印( b ,-, c )
移动(1, a , b , c )
n=1:
打印( a ,-, c )
//到这里,通过A把B上的盘子移到C上,
//执行全部代码,完成ajdnm移动。
最终的打印结果是:
童鞋们可以在了解ajdnm的递归算法原理后,写个程序试试。在这里,他们只学Python的递归,所以用Python。童鞋可以用其他语言实现。ajdnm确实可以帮助他们理解递归原理。递归在编程中的重要性不言而喻!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。