汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
如果只有一个盘子,那么移动的步骤就是将 a上的一个盘子挪到 C,
记作 A -> C
如果有两个盘子,则先把A上的一个盘子挪到B,然后将A上的最大的盘子挪到C,最后把B上的盘子挪到C,记作
A->B
A->C
B->C
如果有三个盘子,重复上面的步骤,可以得到:
A->C
A->B
C->B
A->C
B->A
B->C
A->C
那么如果有n个盘子呢?如何将A上的n个盘子挪到C上?
一步一步拆解比较难,不妨将A上的上面 n-1 个盘子看做一个整体,并将其从A上挪到B上,然后将A上的最大的盘子从A上挪到C上,那么问题就变成了,如何将B上的 n-1 个盘子从B上挪到C上。如图
如何构建n和n-1之间的关系?
如果这样还看不出来的话,把图换个位置再看看:
可以发现,其实A上没有盘子,C上有一个最大的盘子,可以盛放所有的大小的盘子,相当于没有盘子,这个时候问题就是如何将B上n-1 个盘子挪到C上,那么这个问题就又回到了第一步中的:
如何将A上的n个盘子挪到C上:如下图
所以接下来就是将B上的n-2个盘子,挪到A上,然后将B上最大的盘子挪到C,最后将A上的n-2个盘子全部挪到C,问题就变成了如何将n-2个盘子如何从A上挪到C,这个时候又需要将借助B。先将A上的n-3个盘子挪到B,然后将A上最大的盘子挪到C.........
可以看出来汉诺塔的递归思路就出来了,他就是不断地借助A柱子和B柱子,将单个盘子,逐个挪到C盘子。
下面是我画的图解
完整代码: java↓↓↓
public class Test { public static void hannota(int n,char A,char B,char C) { if(n == 1){ move(A,C); return; } hannota(n-1,A,C,B); // 将n-1个盘子从A经过C挪到B上 move(A,C); // 将 A上的盘子挪到C上 hannota(n-1,B,A,C); // 再将n - 1 个盘子从B经过A挪到C上 } public static void move(char a,char b){ System.out.print(a+"->"+b+" "); } public static void main(String[] args) { hannota(1,'A','B','C'); // 测试一个盘子 System.out.println(); hannota(2,'A','B','C'); // 测试两个盘子 System.out.println(); hannota(3,'A','B','C'); // 测试三个盘子 } }
python版本↓↓↓
def hannota(n, A, B, C): #将 A柱子上的N个盘子经过B挪到 if n == 1: # C上 move(A, C) return else: hannota(n - 1, A, C, B) #将N-1个盘子从A经过B挪到 # C上,和我们上面的图一一对应 move(A, C) # 打印这一步 hannota(n - 1, B, C, A) # 继续,将n-1个盘子从B经过A def move(pos1, pos2): # 挪到C上。 print(pos1, ' -> ', pos2, sep='') hannota(5, 'A', 'B', 'C')