汉诺塔递归问题
# include & ltiostream & gt
使用命名空间std
of stream fout(" out . txt ");
void Move(int n,char x,char y)
{
fout & lt& lt“吧”< & ltn & lt& lt"编号来自" < & ltx & lt& lt"移动到"
}
void Hannoi(int n,char a,char b,char c)
{
如果(n==1)
Move(1,a,c);
其他
{
汉诺伊(n-1,a,c,b);
Move(n,a,c);
汉诺伊(n-1,b,a,c);
}
}
int main()
{
fout & lt& lt“以下是河内七层塔的解法:”
Hannoi(7,' a ',' b ',' c ');//调用
fout . close();
cout & lt& lt“输出完毕!”& lt& ltendl
返回0;
汉诺塔是用递归方法实现的。
可能你还没有完全理解递归。无论如何,记住程序总是按顺序一步一步执行的。如果调用了一个函数,就在被调用的地方设置一个断点,变成函数执行,执行后再返回断点。永不改变!
程序执行顺序
Hannoi(7,' a ',' b ',' c ');这里调用函数,执行函数,传入参数n=7。
第一步执行判断语句,根据n的值进入else执行。
第二步,执行Hannoi(n-1,a,c,b);这时候函数本身就叫递归。可以看到n-1的传入值相当于n=6的传入值和a、c、b的值,注意顺序。调用时,a、c、b的值是第一个传入的值。
第三步是执行Hannoi(int n,char a,char b,char c)函数,这个可以理解。这次传入的值n是6,但是a,b,c的值与第一个值相比发生了变化,可以理解为,a (2) = a (1),b(。这里括号代表函数调用的次数。这里最容易混淆的其实是A、B、C的值,如果你用自己的本子把A、B、C的值按来货顺序列出来,会更好理解。
同样,执行判决,n & gt1进入else,按顺序执行,先执行Hannoi(n-1,a,c,b);然后调用本身,注意传入的值,分别是A (2),C (2),B (2),然后去执行Hannoi(int n,char a,char b,char c)函数。这时候收到的值A (3) = A (2),B (3) = C (2),C .给自己做个表以后整理一下。
如此循环往复,直到n=1。看Hannoi(n-1,a,c,b);每次N减1,所以递归n-1的时候,直接执行if(n==1),最后已经改了吧?他执行Move(1,a,c);即输出函数在执行Move(int n,char x,char y)后返回到原调用的断点。继续倒退。如果没有语句,将返回上次调用的函数。最后一个调用Hannoi(int n,char a,char b,char c)的是谁?n-2次是Hannoi(int n,char a,char b,char c)中的Hannoi(n-1,a,c,b);叫他,回到这里,继续向后满足Move(n,a,c);这里不需要解释了。输出后回来继续向后执行Hannoi(n-1,b,a,c)。新的递归开始了。让我们列一份新的清单。注意传入的值及其顺序,以及此时n的值是什么。
其实你可能看不太清楚我的解释。关键是要明白,递归无非是调用自己,调用后返回是返回到他上次调用的地方,也是自己,只是两次使用的函数值不同。最好做好笔记,多写几遍,便于理解和分析。
这个递归程序很经典,值得研究。你会发现它是如此的巧妙和伟大!测试时建议不要设置n太大,否则容易死机!想想里面的循环次数就很神奇!