我们在网上搜索汉诺塔问题的时候,绝大部分教程都只告诉我们问题描述、解决思路(用递归balabala..)、然后就是源代码(如下)
```c
#include<stdio.h>
#include<math.h>
void h(int n,char A,char B,char C)
{
void move(char x,char y);
if(n==1) move(A,C);
else
{
h(n-1,A,C,B);
move(A,C);
h(n-1,B,A,C);
}
}
void move(char x,char y)
{
printf("%c-->%c\n",x,y);
}
void main()
{
int n;
scanf("%d",&n);
h(n,'a','b','c'); //细节上或有些许不同,稍加理解即可,递归过程如下文
}
然而,却很少看到有作者详细介绍每一次递归如何输出,每一次数据如何进入函数h()。
那么接下来,我们就探讨一下,汉诺塔问题n步递归的具体过程。
1.要探讨递归,我们首先要搞清楚递归的跳出条件,很明显h()中跳出条件为n==1;
当n==1时,调用move函数进行一次输出。
重点一 :move(A,C)中A,C并非调用主函数中实参’a’,‘b’,‘c’,而是h()中形参A,B,C;务必理解此句,然后读者就能理解为什么输出只有move(A,C),结果中却有a->b,a->c,b->c。
接着我们以n==2为例子 ”进入”函数。
首先,输入n=2,函数h(2,‘a’,‘b’,‘c’)开始执行,此时n!=1,所以进入
进入函数h(n-1,A,C,B)开始递归!
此时h(n-1,A,C,B)为h(1,A,C,B),注意,顺序为A,C,B(意为将1块圆盘从A通过C送到B);
一次递归函数h(1,A,C,B)执行,此次n==1,执行move(A,C),因为A,C为形参,所以输出A,C对应位置的实参’a’,‘b’,注意,此时形参C对应实参为’b’,务必
理解。
所以n==2的情况下,一次递归即跳出,输出a->b;
好,到这里如果能够理解,那么后面的部分就都是重复体力活了。
一次递归跳出后,返回h(2,‘a’,‘b’,‘c’)(可能读者对大小写会有疑惑,我在编程时将形参统一大写,实参统一小写,如上文所示,便于理解)
接着运行
此处move(A,C)是将h(2,‘a’,‘b’,‘c’)中A,C所对应实参输出,所以输出a->c。
最后运行
按照h(1,A,C,B)相同做法即可得出b->c;
所以能够得到结果
当n>2时,则需要多进行n-2次递归,有些费时间,但只要能理解上文,应该也都能消化,若有问题或者说明不到位的地方,欢迎评论指出,我会及时回复!