问题背景

汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?

新人初识c语言,对汉诺塔问题的简单探讨_汉诺塔问题

数学分析

准备:将3根柱子从左至右分别命名为A B C,假设A柱上有n个圆盘,记将n个圆盘从A柱移动至C柱所需步骤数为a(n)个。

分析:由于在小圆盘上不能放大圆盘,故想将A上圆盘移至C上,则需将前n-1个圆盘移至B上,再将最下方圆盘移至C上,再将n-1个圆盘移至C。由于将圆盘由A移至C与将圆盘由A移至B在步骤数上是相等的。个a(n)=a(n-1)+1+a(n-1)=2a(n-1)+1,显然a(1)=1

代码

代码 计算步骤数:

新人初识c语言,对汉诺塔问题的简单探讨_递归_02

运行结果:

新人初识c语言,对汉诺塔问题的简单探讨_汉诺塔问题_03

代码 展示全步骤:

新人初识c语言,对汉诺塔问题的简单探讨_汉诺塔问题_04

运行结果:

新人初识c语言,对汉诺塔问题的简单探讨_汉诺塔问题_05

代码分析:

第一段:代码为简单的递归,形式类似于抽象函数。

第二段:

新人初识c语言,对汉诺塔问题的简单探讨_c语言_06

将n个圆盘由A->C,可分为三步,第一步为将n-1个圆盘由A->B,将剩下一个圆盘由A->C,再将n-1个圆盘由B->C。

可以注意到,进行递归是应该按照上图顺序,而第一步中,原由A->C被改为由A->B,即C被替换为B,故书写代码时应将B与C的位置替换,即:

新人初识c语言,对汉诺塔问题的简单探讨_递归_07

第三步同理,即:

新人初识c语言,对汉诺塔问题的简单探讨_汉诺塔问题_08

而第二步依旧为:

新人初识c语言,对汉诺塔问题的简单探讨_c语言_09

A->C,是因为在进行第一步与第三步递归过程中,B与C或A与B已被替换,故无需更改。

而在接下来的递归过程中,如n-1(A->B)的递归中,由于B与C被替换,故等效为n-1(A->C),即最开始的流程,同理,每一次递归均满足上述3步。

体会

初识c语言进行编程,对我而言是一件颇有难度的事,但同时也获得了相当大的收获,如对递归过程理解更为深刻,也体会到了代码世界的乐趣,而第一次像这样书写文章,向他人分享自己的思路也让我的思考更加深刻,更加简练。

感言

这是本人第一次写这样的文章,在许多方面有很多不足,请大家多多见谅,有问题请指出,谢谢!