摘要:汉诺塔问题是源于印度一个益智游戏。在三柱子上按从小到大的顺序摞着64片圆盘。要求把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。面对汉诺塔问题我们可以将其想想成一个抽象的数学问题,利用计算机的递归算法对汉诺塔问题进行简单的算法分析求解。
关键词:汉诺塔问题、递归算法
1引言
汉诺塔是一个发源于印度的益智游戏,也叫河内塔。相传它源于印度神话中的大梵天创造的三个金刚柱,一根柱子上叠着上下从小到大64个黄金圆盘。大梵天命令婆罗门将这些圆盘按从小到大的顺序移动到另一根柱子上,其中大圆盘不能放在小圆盘上面。当这64个圆盘移动完的时候,世界就将毁灭。
而递归算法在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。
因此递归算法是解决汉诺塔问题的最简单方法。递归是将重复将问题分解为同类的子问题而解决问题的方法,而汉诺塔问题就是一个不停重复同一个问题的过程。所以递归算法是解决汉诺塔问题的最合适的方法。
我们可以通过递归算法的思想将汉诺塔问题分成N个问题并且这N个问题与原题目相同且独立,让每一层递归所算的问题都是原问题上的一个小问题,直到每个小问题都解决完毕,也就解决掉了最开始的汉诺塔大问题。而要实际解决汉诺塔问题我们大致分为:将问题抽象为数字问题;寻找规律,分解问题;列出步骤,算法分析;写出代码完成解题。
首先将汉诺塔问题抽象为数字问题,建立数学模型是为了更好的看清题目,更方便容易的从题目中找到关键点,以此来分解问题,列出式子,再找出其中规律。我们将抽象的数学问题将分割成n个小问题,然后根据每个小问题的算法,找出所有小问题的共同点,找出规律,再根据每个小问题的解决步骤写出程序算法,然后汇总出最终程序步骤即可。层层递归层层解决,逐步解决。这样就可以快速解决汉诺塔这个较为复杂的问题。
2 汉诺塔实例
如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数。
要解决这个问题我们需要用到的计算机的递归算法,要用计算机来解决问题首先我们需要将他抽象为数字问题,将他建立成一个数学模型,将其分解成一个一个小问题。我们根据盘子数可将其按盘子数量进行分解,将每个盘子都分解成一小问,看看盘子的个数会不会影响移动盘子的次数,根据移动次数的改变,找出规律。
我们设n为盘子数,因此我们移动盘子的规律为:
(1)n=1时我们只需要将A移到C即可。
(2)当n=2时我们则将A移到B,再将A移到C,然后将B移到C。
(3)当n=3时同样先将A移到C,再将A移到B,再将C移到B,再将A移到C,B移到A,B移到C,A移到C(如下图所示)
到此时我们不难发现一个规律那就是:圆盘次数的n次方减1即为它所要移动的次数。即:2n-1。
3 递归算法解决汉诺塔问题
发现规律后我们接下来要想的问题就是分析算法,将其用代码呈现出来。
在应用算法的时候我们首先要注意到题目给出的限定性要求:小圆盘上不得放大圆盘;每次只能移动一个圆盘。
根据上面的引例我们已经得到了一个移动次数的规律为2n-1。接下来我们需要将此规律转化为计算机语言,并且用递归法来解决问题。从开始的时候我们先设想我么输入盘子数为1,然后进入主函数main将盘子从A移到C,当我们输入盘子数依次增多时将其重新调用另一个函数,将n-1个盘子从A移到B,再将A的第n个盘子移动到C,最后将B上的n-1个盘子移到C上,最后输出。我们将n=1和n>1的所调用的函数分开调用,但都编写在main主函数中。让其不停调用函数,直至所有盘子都已参与完运算。
具体代码如下:
public class Hanoilmpl {
public static void hanoi(int n,char A,char B,char C){
if(n == 1){
mov(A,C);
}
else {
hanoi(n - 1,A,C,B);//将n-1个盘子由A经过C移动到B
mov(A,C); //执行最大盘子n移动
hanoi(n - 1,B,A,C);//剩下的n-1盘子,由B经过A移动到C
}
}
private static void mov(char A,char C){//执行最大盘子n的从A-C的移动
System.out.println("move:" + A + "--->" + C);
}
public static void main(String[]args){
System.out.println("移动汉诺塔的步骤:");
hanoi(3,'a','b','c');
}}
以上代码,就是按照上述所说编写的递归代码,层层递归,将逐个小问题依次解决,最后使所有盘子一次经过该程序的运算,得到最终答案。
4结论
运用递归算法来解决汉诺塔问题实际上只是将汉诺塔问题进行分解,使其变得更加简单化。将原题分解为多个与原题相同的小问题,找到一个小问题的答案然后逐步进阶,逐个问题逐个问题的解决。找出他们的相似之处运用一个规律运用递归不停调用,也就找到了最终的解决方法因此递归也是最简单的求解汉诺塔的方法。
参考文献:
[1]马健喆.汉诺塔算法的分析与设计[J].计算机时代,2015(8):49-51.
[2]张学刚.解决递归问题的网络游戏性课件的设计研究与实现[D].吉林大学.2008.
[3]Rnan_Wang.汉诺塔的图解递归算法.2018.
[作者简介]赵东明,男,山东协和学院计算机科学与技术专业在读本科生。宫琳琳(1983),指导教师,通讯作者,女,山东青岛,本科,副教授,研究方向:软件技术,教育管理。
论文作者:赵东明,宫琳琳
论文发表刊物:《基层建设》2019年第14期
论文发表时间:2019/7/26
标签:递归论文; 盘子论文; 圆盘论文; 算法论文; 移到论文; 汉诺论文; 柱子论文; 《基层建设》2019年第14期论文;