背景:
在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。
印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。
不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。
僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
汉诺塔就相当于有ABC三根柱子,目标是要将A柱的所有金片移动到C柱子。移动过程中必须遵循小片在大片上面
这是我见过的比较诡异的递归题目,难度在于他递归调用时候参数的变换。结合示例代码来看这个问题
public class HanoiTower { public static void main(String[] args) { //盘子的数量,按照最简单的方式来理解,比如有两个金片(可以将最大的金片当作第一个,上面所有的金片看成第二个金片) int plate = 2; //调用move方法移动金片 new HanoiTower().move(plate,"A","B","C"); } //递归的移动方法。参数一次为:金片的个数,从那个柱子移动,经过哪个柱子,最终想要移动到的柱子 public void move(int n, String from, String aux, String to) { //退出条件 //移动第一个金片,n=1,这里可以做个假设,比如只有一个金片,那么带入到这个方法后,直接是从A移动到C,返回递归方法。 //这也是整个递归的输出的第一句话 if (n == 1) {//金片数量为1,移动后达成递归条件返回 System.out.println("移动 盘子" + n + "从" + from + "到" + to); return; } //递归调用,移动该金片下面大的金片,从A移动到B,借助C,这是移动顶端金片前的一部操作 move(n - 1, from, to, aux); //当第一枚金片移动到C后,开始倒叙输出,将第2枚金片 System.out.println("将盘子" + n + "从" + from + "移动到"+ to); //收尾工作,就是最底下那枚金片移动到C柱后,需要将剩下的金片从辅助柱子移动到目标柱子。。 move(n-1,aux,from,to); } }
实话说如果没有看到其他人的解题方法,我也是想不到居然是这样操作。不过递归的整体逻辑还是没有变化,
1、设置递归退出条件
2、设置递归尝试的逻辑
3、尝试逻辑不断逼近递归退出条件,待达成退出条件后,开始递归出栈。
汉诺塔的递归代码非常的简短,但是确实难以理解。
我认为最好的办法就是缩减金片的数量,假设1枚、2枚、3枚金片进行逐步推理。 测试通过后再进行累加。验证
评论(已关闭)
评论已关闭