1 问题
(n阶汉诺塔问题)假设有3个分别命名为X、Y和Z的塔座,在塔座X上插有n个直径大小各不相同、依小到大编号为1,2,…,n的圆盘。现要求将X轴上的n个圆盘移至塔座Z上并仍按同样顺序叠排,圆盘移动时必须遵循下列规则:
1)每次只能移动一个圆盘
2)圆盘可以插在X、Y和Z中的任一塔座上
3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。
2 分析
当n=1时,只要将编号为1的圆盘从塔座X直接移至塔座Z上即可;
当n>1时,需利用塔座Y作辅助塔座。若能设法将压在编号为n的圆盘之上的n-1圆盘从塔座X移至塔座Y上,则可先将编号为n的圆盘从塔座X移至Z上,然后在将塔座Y上的n-1圆盘移至塔座Z上。而如何将n-1圆盘从一个塔座移至另一个塔座的问题是一个和原问题具有相同特征属性的问题,只是问题的规模小,因此可以用同样的方法求解。
3 实现
#include <stdio.h>
int step = 1;
void move(char a, int n, char b)
{
printf("<%2i> move %d from %c -> %c\n", step++, n, a, b);
}
void hanoi(int n, char x, char y, char z)
{
if (n == 1)
{
move(x, 1, z); /*将编号为1的圆盘从X移至Z*/
}
else
{
hanoi(n-1, x, z, y); /*将X上编号为1至n-1的圆盘移至Y,Z作辅助塔*/
move(x,n,z); /*将编号为n的圆盘从X移至Z*/
hanoi(n-1, y, x, z); /*将Y上编号为1至n-1的圆盘移至Z,X作辅助塔*/
}
}
int main()
{
hanoi(4,'X','Y','Z');
return 0;
}
输出:
< 1> move 1 from X -> Y
< 2> move 2 from X -> Z
< 3> move 1 from Y -> Z
< 4> move 3 from X -> Y
< 5> move 1 from Z -> X
< 6> move 2 from Z -> Y
< 7> move 1 from X -> Y
< 8> move 4 from X -> Z
< 9> move 1 from Y -> Z
<10> move 2 from Y -> X
<11> move 1 from Z -> X
<12> move 3 from Y -> Z
<13> move 1 from X -> Y
<14> move 2 from X -> Z
<15> move 1 from Y -> Z