递归是编程中的一种常见思想,它用于将大问题拆分成小问题,使问题得以简单化。
本篇文章要讨论的汉诺塔问题就可以用递归的方法解决
目录
汉诺塔问题简介
汉诺塔又被称为河内塔,传说,在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
汉诺塔思路分析
动图展示:
通过上图观察可知:
1层汉诺塔:A➜C(移动1次)
2层汉诺塔:A➜B A➜C B➜C(移动3次)
3层汉诺塔:A➜C A➜B C➜B A➜C B➜A B➜C A➜C(移动7次)
不难得出以下两个规律:
移动次数规律:2^n-1
移动方法规律:1.把A柱上n-1块盘子通过C柱移到B柱上 2.把A柱上的最后一块盘子移动到C柱上 3.把B柱上n-1块盘子通过A柱从B柱移动到C柱上
将第n块移动到C柱上之前需要将n-1块移动到C柱上,这就符合递归的思想。
汉诺塔代码详解
通过上述分析我们已经对汉诺塔的原理有了一定的了解,那该如何通过递归去解决汉诺塔问题呢?
首先需要写个输出函数指明该步骤是将哪个盘子从哪个柱子移动到哪个柱子上:
public static void move(char pos1,char pos2) { System.out.print(pos1+"->"+pos2+" ");//从pos1柱上移动到pos2柱上 }
接下来就是通过上面的移动方法规律实现递归函数了:
(下面hanoi(n, pos1, pos2, pos3)意思是:将n个在pos1柱子上的盘子通过pos2这个柱子移动到pos3这个柱子上)
public static void hanoi(int n,char pos1,char pos2,char pos3) { //递归的结束条件 if(n == 1) { move(pos1,pos3);//相当于1层汉诺塔时 return; } //递归公式 hanoi(n-1,pos1,pos3,pos2);//把A柱上n-1块盘子通过C柱移到B柱上 move(pos1,pos3);//把A柱上的最后一块盘子移动到C柱上 hanoi(n-1,pos2,pos1,pos3);//把B柱上n-1块盘子通过A柱从B柱移动到C柱上 }
注:用递归求解问题时, 不要试图跟踪大型递归的过程,关键在于找出递归的递归方程式,即要完成某一步,那么某一步的前一步要干嘛。在求hanoi(n, pos1, pos2, pos3)的时候,你就默认f(n -1, pos1, pos2, pos3)已经被求出来了,至于怎么求的,这个就交给计算机就好啦~
完整代码如下
import java.util.Scanner; public class Test { public static void move(char pos1,char pos2) { System.out.print(pos1+"->"+pos2+" "); } public static void hanoi(int n,char pos1,char pos2,char pos3) { if(n == 1) { move(pos1,pos3); return; } hanoi(n-1,pos1,pos3,pos2); move(pos1,pos3); hanoi(n-1,pos2,pos1,pos3); } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while(scanner.hasNextInt()) { int n = scanner.nextInt(); hanoi(n, 'A', 'B', 'C'); System.out.println(); } } }
本期用递归解决汉诺塔就介绍这了,谢谢观看✿✿ヽ(°▽°)ノ✿