美文网首页C语言
彻底解决——C递归算法汉诺塔问题

彻底解决——C递归算法汉诺塔问题

作者: 孟孑 | 来源:发表于2020-03-12 22:57 被阅读0次

文/孟捷

法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。(摘自百度百科)

汉诺塔,这个有趣的数学问题便来源于以上这个古老的传说,通过上面的故事,我们可以理解到:汉诺塔游戏建立在两条规则之上——①一次只能移动一个圆盘;②小圆盘始终要在大圆盘之上。这两条规则是我们解决问题的出发点。

当圆盘数量为64时,经过科学的计算,若每次移动圆盘需要耗时1微妙,那么将64个圆盘全部移动到另一根柱子上需要60万年,可见这是一个非常复杂的问题。

那么现在想要解决这个问题,我们可以对其简化:假设A柱子上有两个圆盘而非64个,那么我们需要怎么样移动才能将这两个圆盘移动到B柱子上面呢?——先将A柱子上的小圆盘移动到C柱子上,再将A柱子上的大圆盘移动到B柱子上,再将C柱子上的小圆盘移动到B柱子上,即需要三个步骤:A→C,A→B,C→B。此时此刻,递归算法正好派上了用场——将第64个层的圆盘当作简化问题的下层圆盘,将前63个圆盘当作底层问题的上层圆盘,那么复杂问题就变成了简化问题,而对于移动前63个圆盘来说,再将第63个圆盘当作下层圆盘,将前62个圆盘当作上层圆盘,这样层层递归,最终解决问题。

用C语言实现如下:

汉诺塔问题解决步骤实现程序

当A柱子上有3个圆盘,即n=3时,得出如下结果:

n=3

那么问题的重点来了,程序是如何输出这个结果的呢?我们依旧是以3为例探讨该问题:

对于递归算法,必须理解的一个关键问题是:每次函数调用完成后,程序返回的地方是上层函数

那么,当我们输入3时,程序在主函数内部依顺序结构自上而下执行语句,执行到Hanoi(n,'A','B','C');时,由主函数调用Hanoi(),此时形实结合:n=3,a='A',b='B',c='C',然后程序开始执行Hanoi(n-1,a,c,b);,继而程序进入第二层嵌套,此时形实结合:n=2,a='A',b='C',c='B',第二层嵌套开始执行Hanoi(n-1,a,c,b);,继而程序进入第三层嵌套,此时形实结合:n=1,a='A',b='B',c='C',此时满足条件n==1,执行Move(n,a,b);,第三层嵌套调用Move(),输出结果中的第一条语句。注意:此时第三层嵌套结束了(相当于第二层嵌套的Hanoi(n-1,a,c,b);执行结束),那么程序返回第二层嵌套中,执行Move(n,a,b);,继而输出本次执行结果的第二个step,继而依顺序结构执行Hanoi(n-1,c,b,a);,程序再次进入第三层嵌套中,此时形实结合:n=1,a='B',b='C',c='A',继而n==1满足条件,调用Move(),输出第三个step——Move 1:from B to C,继而第二层嵌套执行结束(相当于第一层嵌套的Hanoi(n-1,a,c,b);执行结束),继而依顺序结构继续执行,以下步骤和上面的思路上差不太多,最终输出7条step。

相关文章

网友评论

    本文标题:彻底解决——C递归算法汉诺塔问题

    本文链接:https://www.haomeiwen.com/subject/lqtgjhtx.html