汉诺塔介绍
汉诺塔由三根柱子组成,开始时所有的圆盘位于1塔上,要求在每次仅移动一个圆盘的情况下,将所有的圆盘由1塔转移到3塔上,注意,在转移过程中,必须保证每个塔上的圆盘自下而上由大到小排列。
题目分析
我们先举几个例子来观察汉诺塔的规律:
一个盘子:
1 0 0
0 0 1(a-c)//从1塔直接转移到3塔
两个盘子:
2 0 0
1 1 0(a-b)//除最大的圆盘外,都先转移到2塔
0 1 1(a-c)//将最大圆盘转移到3塔
0 0 2(b-c)//再将2塔上圆盘转移到3塔
三个盘子:
3 0 0
2 0 1(a-c)//借助3塔
1 1 1(a-b)
1 2 0(c-b)//除最大的圆盘外,都先转移到2塔
0 2 1(a-c)//将最大圆盘转移到3塔
1 1 1(b-a)//借助1塔
1 0 2(b-c)
0 0 3(a-c)//再将2塔上圆盘转移到3塔
可见,在转换的过程中,都会存在一个固定的规律:除最大的圆盘外,都先转移到2塔,再将最大圆盘转移到3塔,最后再将2塔上圆盘转移到3塔。而在这期间,会借助到空的塔以达到每一步后每个塔上的圆盘自下而上由大到小排列。
代码实现
#include <stdio.h>
void move(int num, char a, char b, char c);//注意,在需要借助其他塔进行交换时,a不一定对于A,b不一定对应B,c同理
int main()
{
int num = 0;
printf("起始塔上有多少个盘子?\n");
scanf("%d", &num);
char a = 'A';
char b = 'B';
char c = 'C';
move(num, a, b, c);
return 0;
}
void move(int num, char a, char b, char c)
{
if (num == 1)
{
printf("%c->%c ", a, c);
}
else
{
move(num - 1, a, c, b);//通过空的塔达到除最大的圆盘外,都先转移到2塔
printf("%c->%c ", a, c);//将最大圆盘转移到3塔
move(num - 1, b, a, c);//再将2塔上圆盘转移到3塔
}
}
总结
解决汉诺塔问题需要用到递归的算法,并且过程较为复杂,规律不好分析,大家可以试着运行4个和5个盘的情况,去寻找其中的规律,加深理解。