1.汉诺塔:
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
2.问题描述:
如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数
(1)当只有一个盘子的时候,只需要从将A塔上的一个盘子移到C塔上;A–>C
(2)当A塔上有两个盘子是,先将A塔上的1号盘子(编号从上到下)移动到B塔上
再将A塔上的2号盘子移动的C塔上,最后将B塔上的小盘子移动到C塔上。
(3)当A塔上有3个盘子时,先将A塔上编号1至2的盘子(共2个)移动到B塔上(需借助C塔),然后将A塔上的3号最大的盘子移动到C塔,最后将B塔上的两个盘子借助A塔移动到C塔上。
同理:
(4)当A塔上有n个盘子时,先将A塔上编号1至n-1的盘子(共n-1个)移动到B塔上(借助C塔),然后将A塔上最大的n号盘子移动到C塔上,最后将B塔上的n-1个盘子借助A塔移动到C塔上。
算法分析:
(1)n ==1
第1次 1号盘 A---->C
移动次数:1
(2)n == 2
第1次 1号盘 A---->B
第2次 2号盘 A---->C
第3次 1号 B---->C
移动次数:3
(3)n == 3
第1次 1号盘 A---->C
第2次 2号盘 A---->B
第3次 1号盘 C---->B
第4次 3号盘 A---->C
第5次 1号盘 B---->A
第6次 2号盘 B---->C
第7次 1号盘 A---->C
移动次数:7
由数学归纳法分析可得:移动次数为:2^n - 1
3.算法实现
实现这个算法可以简单分为三个步骤:
(1) 把n-1个盘子由A 移到 B;
(2) 把第n个盘子由 A移到 C;
(3) 把n-1个盘子由B 移到 C;
(1)中间的一步是把最大的一个盘子由A移到C上去;
(2)中间一步之上可以看成把A上n-1个盘子通过借助辅助塔(C塔)移到了B上,
(3)中间一步之下可以看成把B上n-1个盘子通过借助辅助塔(A塔)移到了C上;
代码及注释:
#include<stdio.h>
void Move(int n, char A, char B, char C)
{
if (n==1)
{
printf("%c-->%c\n",A,C);
}
else
{
Move(n - 1, A, C, B);//把A上n-1个盘子通过借助辅助塔(C塔)移到了B上
printf("%c-->%c\n", A, C);//把最大的一个盘子由A移到C上去
Move(n - 1, B, A, C); //把B上n-1个盘子通过借助辅助塔(A塔)移到了C上
}
}
int main()
{
int n = 0;
printf("请输入汉诺塔的盘子数:");
scanf("%d", &n);
Move(n, 'A', 'B', 'C');
return 0;
}