汉诺塔问题是什么?
通俗的说,给你三根立柱,分别命名为A、B、C,在A上有数量为n的盘子,并且这些盘子以从下到上,从大到小的顺序放置,现在需要你将A上的盘子挪动到C上去,要求:每次只能挪动一个盘子,并且在挪动过程中必须保证盘子在立柱上始终以从下到上,从大到小的顺序放置。
解题思路如何构建?
在函数递归的学习中,我们知道运用递归的知识可以将一些复杂问题拆解成为一个个简单问题,那么汉诺塔就可以是一个复杂问题,那么我们只需要想最简单的情况,即假设只有两个圆盘,那么显而易见的解决方法就是:A->B,A->C,B->C,倘若此时增加圆盘数量为n,那么我们就可以将这n个盘子分为两部分,一部分是从1到(n-1),另一部分是最底下的一个盘子n,这两部分我们就可以看成是最简单的情况(两个盘子),而1到(n-1)我们也可以分化为两部分,即1到(n-2)为一部分,n-1为一部分,朋友们有没有发现此时我们就完成了函数递归了呢,我们已经将复杂的问题简单化了。
图一:表示的是将1到(n-1)看成一个盘子,将n看成一个盘子。
图二:将1(1到(n-2))看成一个盘子,将n-1看成一个盘子。(递归思想)
这里需要注意的是大家不要忽略了③中B的处理,即需要递归的不仅是从A到B,还有从B到A的递归,图中没有画出,但是思路是一样的。
如此不管n为多少,我们都可以将n无限的分为两部分,这样一来只要我们知道汉诺塔最简单情况即两个盘子的情况如何解决就可以了,这也充分说明了函数递归的巧妙:复杂问题简单化。
代码实现
#include<stdio.h> void move(char m,char n) { printf("%c->%c\n", m, n); } void hanoi(int n, char a, char b, char c) { if (n == 1) move(a, c); else { hanoi(n - 1, a, c, b);//ps① move(a, c); //ps② hanoi(n - 1, b, a, c);//ps③ }//关于这里如果大家没看懂,我在后续说明中再做讲解。 } int main() { int num = 0; scanf_s("%d", &num); printf("盘子的数量为:%d\n", num); hanoi(num, 'A', 'B', 'C'); return 0; }
注意:实参A、B、C与形参a、b、c不同,大家不要搞混,a、b、c更多的可以理解为柱子顺序。
后续说明在这里:大家有没有发现在A->B中明显涉及到了复杂问题拆分,即将1到n-1看成一个盘子,所以需要第一个递归ps①,而ps②中并没有涉及到递归,大家结合图片就能知道了,而ps③涉及到的是在B->A时,与ps①同理,也是将复杂问题拆分,这里大家搞懂ps①的递归后,不妨尝试理解ps③,相信这样可以让你理解的更加深入。
总结
有时候可能更多的需要大家去画图并实操,仅仅看一两篇文章就能吃透不太现实,拒绝拿来主义,伙伴们,动起来💪💪💪
希望这篇文章可以对你有所帮助。