汉诺塔递归问题

# include & ltfstream & gt

# 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太大,否则容易死机!想想里面的循环次数就很神奇!