目录
问题描述:
如果有n个盘子为例 我们怎么 借助一个B盘 把所有的盘子 从A柱移动到C柱 ?
问题关键:
- 每一次只能移动一个盘子
- 时刻保证大的盘子在小的盘子下面
- 只能移动在最顶上的圆盘 (不可以直接动上面有东西的盘子!)
我们首先以两个为例
很容易想到 只需要3步
1. 先把上面的盘子移动到B柱
2. 把下面的大盘子移动到C柱
3. 把B柱上面的小盘移动到C上
即:
那么这是两种情况 如果有n个盘子呢?
我们可以把 上面的n-1个 盘子
然后进行盘子数为两个时的操作:
1. 先把上面n-1个盘子 移动到B柱
2. 再把 A柱上第n个盘子 放到C柱
3. 把B上面n-1个盘子移动到C柱
不过 规则是 每一次只能移动一个盘子 那这种方法是否可行呢?
我们先利用代码验证一下
很显然 利用函数递归可以实现:
C语言代码:
void hannuota(int n, char a, char b, char c)
{
if (n == 1)//说明 只有一个盘子 那么只需要将盘子从a移动到c即可
{
printf("move sheet from %c to %c\n", a, c);
}
else
{
hannuota(n - 1, a, c, b);
//函数递归思想,将a里面最后一个盘子上面的n-1个盘子当成一个盘子
//首先移动到b上 那么这里就需要多次递归实现 因此abc的实际作用也会发生改变
hannuota(1, a, b, c);//将 a中剩下的最大的盘子 移动到c上
hannuota(n - 1, b, a, c);//将b中的n-1个盘子 放到 c中 再一次需要递归!
}
}
int main()
{
int n = 0;
char a = 'A';
char b = 'B';
char c = 'C';
printf("请输入盘子数: ");
scanf("%d", &n);
hannuota(n, a, b, c);
return 0;
}
但是 具体的递归细节 我们是不是正确的呢 ?
我们看一下结果
经过验证是正确的
不过 具体的递归细节 是怎么实现的呢?
当然这样 单想 是很难想的
我用画图把 以三个盘子为例 每一个递归过程 展示一下
画图展示过程:
画图不易
但不管怎样 经过验证 是正确的!!
整个方法 是 把n-1,n-2.... 大于1个盘子数的情况 看成一个整体
而实际上是不断地 改变 盘子起始移动柱和盘子终点柱 从而一个一个把这些整体 以单步的形式实现转移
这就是我对汉诺塔问题的理解