假设你已经懂了汉诺塔的规则。
#include <stdio.h>
void move(char a,char c,int n);
void hannuota(int n,char a,char b,char c);
int main()
{
int n;
scanf("%d",&n);
char a='a',b='b',c='c';
hannuota(n,a,b,c);
return 0;
}
void move(char a,char c,int n)
{
printf("第%d个盘子从%c-->%c\n",n,a,c);
}
void hannuota(int n,char a,char b,char c)
{
if (n==1)
{
move(a,c,n);
}
else
{
hannuota(n-1,a,c,b);
printf("第%d个盘子从%c移动到%c\n",n,a,c);
hannuota(n-1,b,a,c);
}
}
这代码反正就是要搞清每一步形参与实参的对应关系,不然容易被绕晕。
先假设有俩盘子,数字较大的盘子为底下的盘子。
一开始我们的形参a,b,c就分别对应我们的实参a,b,c.
因为n不等于1所以我们只要是要弄懂else部分的递归。
else
{
hannuota(n-1,a,c,b);
printf("第%d个盘子从%c移动到%c\n",n,a,c);
hannuota(n-1,b,a,c);
}
此时读到hannuota(n-1,a,c,b);就相当于hannuota(1,a,c,b);
此时形参对应的实参值就发生了变化。
形参a还是a.但是形参b的值为c,形参c的值变为b.
接下来那就执行hannuota(1,a,c,b),因为满足n=1,执行move(a,c,n),move里的a,c是指形参a,c对应的字符也就是a,b.就这样hannuota(n-1,a,c,b);运行结果打印了
第1个盘子从a-->b;
也就结束了。
然后接着下一句代码
printf("第%d个盘子从%c移动到%c\n",n,a,c);
要注意这里的形参a,c对应的值和上一句代码
hannuota(n-1,a,c,b);
没有联系。
形参a,c的值就是你主函数里给的值,a,c.
n=2.
就打印了
第2个盘子从a移动到c
最后一句代码与hannuota(n-1,a,c,b);同理。
--------------------------------------------------------------------------输入n=3.
第一步hannuota(n-1,a,c,b);
也就是hannuota(3-1,a,c,b).
此时形参a还是a.但是形参b的值为c,形参c的值变为b。
此时开始递归。
注意此时调用了hannuota(3-1,a,c,b)
我们此时脑中想的应为这串代码
void hannuota(int n,char a,char b,char c)
hannuota(3-1,a,c,b)
{
if (n==1)
{
move(a,c,n);
}
else
{
hannuota(3-1-1,a,c,b);
printf("第%d个盘子从%c移动到%c\n",n,a,c);
hannuota(3-1-1,b,a,c);
}
}
hannuota(2,a,c,b)
2不满足等于1的条件
往下又遇到了
hannuota(n-1,a,c,b);
此时,也就是hannuota(3-1-1,a,c,b);此时形参a,c,b实际值为a,b,c.也就是调用函数实际输入值为a,b,c.
那么执行它就会满足等于n=1的条件然后执行move(a,c,n),此时形参a,c对应值为a,c.也就打印了第1个盘子从a-->c。
hannuota(2-1,a,c,b);结束。
回到hannuota(3-1,a,c,b).完成了hannuota(2-1,a,c,b),继续往下也就是printf("第%d个盘子从%c移动到%c\n",n,a,c);
此时形参a,c的值为a,b也就打印出
第2个盘子从a移动到b
最后hannuota(3-1-1,b,a,c);此时hannuota(3-1-1,b,a,c);内部的形参对应为实参c,a,b.
执行它得到move(a,c,n);的打印结果。
此时内部形参对应实参为c,b.
打印结果第1个盘子从c-->b。
到此第一个调用函数(hannuota(n-1,a,c,b);)结束。
下面执行
printf("第%d个盘子从%c移动到%c\n",n,a,c);
此时n为3,a为a. c为c.
打印结果 第3个盘子从a移动到c。
然后
最后一次调用,自定义函数最后一句需执行代码hannuota(n-1,b,a,c);
也就是hannuota(2,b,a,c)此时形参a,b,c对应实参b,a,c.
执行hannuota(2,b,a,c)
脑中浮现
void hannuota(int n,char a,char b,char c)
hannuota(3-1,b,a,c)
{
if (n==1)
{
move(a,c,n);
}
else
{
hannuota(3-1-1,a,c,b);
printf("第%d个盘子从%c移动到%c\n",n,a,c);
hannuota(3-1-1,b,a,c);
}
}
hannuota(3-1-1,a,c,b);形参a,c,b对应实参b,c,a.
move(a,c,n);形参对应实参b,a也就打印了
第1个盘子从b-->a
然后
printf("第%d个盘子从%c移动到%c\n",n,a,c);
a,c形参对应实参b,c
打印第2个盘子从b移动到c
最后hannuota(3-1-1,b,a,c);
形参b,a,c对应实参为a,b,c 也就是说这次调用的函数实际输入参数为a,b,c.
move(a,c,n);形参a,c对应实参a,c
打印第1个盘子从a-->c
hannuota(3-1,b,a,c)结束
递归结束。