递归经典题(汉诺塔)
什么是汉诺塔呢???
汉诺塔(Tower of Hanoi),又称河内塔。源自印度古老传说的一个游戏,大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
一个盘子
只有一个盘子的时候,就比较简单了。如图,只需要一步,直接把 第 1 个盘子从 A移动到 C就完成了。
两个盘子
两个盘子的时候,也比较简单,如下图,只需要借助一下 B 柱子即可完成。
这个过程可以表述为:
把第1个盘子从A移到B
把第2个盘子从A移到C
把第1个盘子从B移到C
三个盘子
三个盘子的时候,稍微复杂一些,但是我们一般也是可以通过心算,把过程推演出来的。
把第1个盘子从A移到C
把第2个盘子从A移到B
把第1个盘子从C移到B
把第3个盘子从A移到C
把第1个盘子从B移到A
把第2个盘子从B移到C
把第1个盘子从A移到C
第n 个盘子:
int a = 0;
void Move(int n,char c,char d)
{
printf("第%d步 ", ++a);//每调用一次Move就代表走了一步,所以++a
printf("把%d号盘,从%c号柱移到%c号柱\n",n, c, d);
}
void Hanoi(int n,char x,char y,char z)
{
if (n == 1)
{
Move(n,x,z);//当n=1,直接将盘子从x移到z上
}
if (n > 1)
{
Hanoi(n - 1,x,z,y);//上面的n-1个盘子,从x借助z(一个一个)移到y
Move(n,x,z);//剩下的一个盘子从x移到z
Hanoi(n - 1,y,x,z);//再将n-1个盘子从y借助x(一个一个)移到z
//把大象放进冰箱三步法
}
}
int main()
{
int n = 0;
printf("请输入圆盘的个数>");
scanf("%d", &n);
Hanoi(n,'X','Y','Z');
return 0;
}
函数具体分析:
一个盘子时,进入函数Hanoi,n=1,执行Move,带去的实参是1,x ,z,所以输出的是
把第一个盘子从x移到z.
两个盘子时,
进入函数Hanoi,n=2,2>1,再次进入函数Hanoi,传的参数是1(n-1)x,z,y,与形参相对应的是n,x,y,z,即在此函数中z用y代替,y用z代替,
第2次进入Hanoi函数后,n=1,执行Move函数,传的参数是1,x,z(y),(传的参数实际上还是第一次的,即y实际就是z,z实际就是y),所以第一次输出的是把第1号盘,从x移动到y.
当(n-1)=1的Hanoi函数执行完之后,又返回去接着执行n=2的Hanoi函数,
,接下来执行Move函数,传的参数是2,x,z.所以第2次输出的是把第2个盘子,从x移动到z.
接下来第3次进入函数Hanoi函数,传的参数是1(n-1),y,x,z,与形参相对应的是n,x,y,z,(即在此函数中x代替y,y代替x,z还是z)
执行函数时,n=1,执行Move函数,传的参数是1,x(y),z,所以输出的把第1个盘子从y移动z。