汉诺塔问题在C语言中一般采用递归法来写,假设有A、B、C三根棒,A棒放着若干个圆盘,将其移动到C棒上,中途可在B棒中暂时放置圆盘。
分析:
(1) 如果只有一个圆盘,则把该圆盘从A棒移动到C棒
(2) 如果圆盘数量n>1,移动圆盘的过程可分为如上图三部分
第一步: 将A棒上的n-1个圆盘移动到B棒上。
第二步: 将A棒上的一个圆盘移动到C棒上。
第三步: 将B棒上的n-1个圆盘移动到C棒上。
其中,第一步和第三步又是移动多个圆盘的操作,又可重复上面的三个步骤来完成这两步中多个圆盘的移动,这样就构成了一个递归过程
根据以上分析,编写程序如下(这里方便编写用1,2,3表示):
#include <stdio.h>
void move(int n,int a,int b,int c) //n为圆盘个数,a移动到c,用b做临时棒
{
if(n==1)
printf("%d——>%d\n",a,c);
else
{
move(n-1,a,c,b); //递归调用,移动a到b,用c做临时棒
printf("%d——>%d\n",a,c);
move(n-1,b,a,c); //递归调用,将b移动到c,用a做临时棒
}
}
int main()
{
int n; //圆盘个数
scanf("%d",&n);
move(n,1,2,3); //1、2、3代表三个棒
return 0;
}
分析代码:
我们需要重点注意,在定义的四个量中,除去定义圆盘的个数n,始终是从第一个变量向最后一个变量移动(不要因为字母的转换而混淆)
当n=2时:
进入else条件内:此n-1=1;
第一个语句:move(n-1,a,c,b);通过第一次递归,因为n=1,所以符合 if 条件,打印printf("%d——>%d\n",a,c); 注意 printf里面的c此时是b !!!即 1——>2
第二个语句:printf("%d——>%d\n",a,c); 此时 :1——>3 (与上一条语句无关,可不要将b和c混淆)
第三个语句:move(n-1,b,a,c); 进行第二次递归,因为n=1,所以符合 if 语句,打印printf("%d——>%d\n",a,c); 注意printf里面a此时是a !!!即2——>3
所以输入n=2时,打印出:
1——>2
1——>3
2——>3
当n=3时:
此时n-1=2;所以可重复上面n=2的操作,进行多次递归时,最最需要注意的就是a,b,c位置的不断变化,只要记住一点,就是永远是打印第一个变量和最后一个变量(这两个量会不断变化,千万千万别混淆a,b,c。
汉诺塔是经典的递归题,在了解与设计该问题时,不要忘记递归的思想,当然汉诺塔也有非递归的作法。。。。。。