递归经典问题———Tower of Hanoi汉诺塔
1.题目及分析
(1)题目
汉诺塔是一种源自古印度的益智游戏,又称河内塔 ,是一个源于印度古老传说的益智玩具 。 大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。 大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。 并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
我们简化一下,就如下图所示
也就是我们需要将这三块木块按照从下到上由小到大的顺序放在C柱子上,并且每次只能移动一块,而且必须保证不能出现大块放在小块上面的情况。
(2)分析
假如只有一块的时候,那只需要挪动一步,从A到C。
那如果是两块呢,三块呢,n块呢?
首先是两块,我就先不为大家画图了,相信大家也能想象出来。
一共需要三步,A到B,A到C,B到C。
而三块呢,如下图所示
第一步:从A到C
第二步:从A到B
第三步:从C到B
第四步:从A到C
第五步:从B到A
第六步:从B到C
第七步:从A到C
重点:相信大家已经发现了,关键点在于前三步,前三步我们将(3 - 1)块都挪到B杆上,最后一块从A到C,之后再将上面的(3 - 1)块挪到C上面。而让我们推广一下,其实两块的时候也是这样操作的,只不过分成了(2 - 1)和1块,那么我们不妨大胆的设想一下,如果有n块,我们就是将最上面的(n - 1)块先挪到B上,之后再挪最后一块从A到C,最后再将(n - 1)块从B挪到C。
2.代码实现
(1)必要分析
a.我们最后需要实现的打印效果是:“最少需要xxx步,之后是挪动的步骤”
b.如何在这个函数里实现挪动和求值。
c.为什么要使用递归呢?原因是:假设有n块,我们先将n - 1去挪动,而这n-1块在挪动时,自然而然又进入到(n - 1 - 1)块需要先动,不断接近n = 1时,将块直接挪的条件,这就满足了递归的条件,不断接近一个界限。
d.其实经过上述分析,也可以发现,还有很重要的一点,其实(n - 1)块是从A借助C挪到B的,相信在上述的移动图片中,大家都已经发现了。
(2)代码实现
#include <stdio.h>
int Hanoi(int x, char qs, char zz, char js)//qs起始,zz中间,js结束
{
if (1 == x)
{
printf("%c→%c\n", qs, zz);
return 1;
}
else
{
return Hanoi(x - 1, qs, js, zz) + Hanoi(1, qs, zz, js) + Hanoi(x - 1, zz, qs, js);;
}
}
int main()
{
int i = 0;
scanf("%d", &i);
int ret = Hanoi(i, 'A', 'B', 'C');
printf("%d\n", ret);
return 0;
}