递归解决汉诺塔问题

  前言:汉诺塔问题是源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在第三根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。


  我们用递归算法来解决这个问题,在解决之前首先介绍一下什么是递归算法。

1、递归算法

         

  在解决一些复杂问题时,为了降低问题的复杂程序,通常是将问题逐层分解,最后归结为一些最简单的问题。这种将问题逐层分解的过程,并没有对问题进行求解,而只是当解决了最后的问题那些最简单的问题后,再沿着原来分解的逆过程逐步进行综合,这就是递归的方法。

  一言以蔽之,递归算法的执行过程分递推和回归两个阶段。在递推阶段,把复杂的问题的分解为简单问题,而且必须要有终止递归的情况。在回归阶段,当获得最简单情况的解后,逐级返回,依次得到稍复杂问题的解。

  在编写递归函数时要注意,函数中的局部变量和参数知识局限于当前调用层,当递推进入“简单问题”层时,原来层次上的参数和局部变量便被隐蔽起来。在一系列 “简单问题”层,它们各有自己的参数和局部变量。

2、解决汉诺塔

           

  对于64个金盘,我们分配64个婆罗门,分别编号为1-64;对于金刚柱,编号为A、B、C。当1号婆罗门接到任务后,发现这个很难完成,然后他想,如果有人把前面63个金盘已经移动到了B号柱子,那么我直接将64号盘放在C上即可,然后他移动前63个金盘的任务交给了2号婆罗门,然后他的任务就变成了:

    ● 让2号婆罗门将前63个金盘移动到B;

    ● 将第64个金盘移动到C;

    ● 让2号婆罗门将前63个金盘移动到C;

  2号婆罗门也犯了难,他想如果有人把前面62个金盘已经移动到了C号柱子,那么我直接将63号盘放在B上即可,然后他移动前63个金盘的任务交给了3号婆罗门,然后他的任务就变成了:

    ● 让3号婆罗门将前62个金盘移动到C;

    ● 将第63个金盘移动到B;

    ● 让3号婆罗门将前62个金盘移动到B;

  3号婆罗门也犯了难,他想如果有人把前面61个金盘已经移动到了B号柱子,那么我直接将63号盘放在C上即可,然后他移动前61个金盘的任务交给了4号婆罗门,就这样递推下去,4号婆罗门又将移动前60个金盘的任务交给了5号婆罗门。。。知道交给64号婆罗门,这时候的任务只需要移动一个金盘了,不需要再去将任务向下分配了。

  这时候分配完成,开始移动:64号婆罗门移开第一个金盘,然后63号婆罗门移动第二个金盘;64号婆罗门再将第一个金盘放到第二个金盘的上边。。。

  可以看出,只有上一个婆罗门的任务完成了,下一个任务才可能完成,这和递归是一样一样的。

  

  这也相当于,每一个婆罗门都对应一个盘子,例如1号婆罗门对应64号金盘,2号婆罗门对应63号金盘, 每个婆罗门只需要移动自己所管的那个盘子就好了。例如1号婆罗门只需要移动自己管的64号金盘,前面的63个,他会叫别人去移动,至于这63个怎么移,那是别人的事,他只要已经移好的结果;同样2号婆罗门也只管自己对应的63号金盘,至于前边62个金盘怎么移,那是别人的事;同样3号婆罗门。。。。。

  可以看出,64个婆罗门都是使用同一个流程的,所以可以用同一个函数表示。而且这个递归是必须有终止条件的,这个条件就是n==1,即任务分配到64号婆罗门,这时候就开始执行任务并向回回溯,分配任务就相当于压栈,执行任务就是弹栈。

3、汉诺塔算法实现

<span style="font-size:18px;">     public void Hanoi(int n, char A, char B, char C)
          //第一列为语句行号
      {
          if (n==1) Move(A, C);
           //Move是一个抽象操作,表示将碟子从A移到C上
         else {
            Hanoi(n-1, A, C, B);
            Move(A, C);
            Hanoi(n-1, B, A, C);
        }
      }
</span>

  对于我们来说,也只是写出递归代码即可,具体运行是电脑的事,我们不用写出。需要理清的是Hanoi(n)和Hanoi(n-1)之间的参数关系,这是和前面婆罗门的任务相对应的,至于Hanoi(n-1)和Hanoi(n-2)的参数关系同上。也就是说我们只需理清前一步和后一步的关系就行了,这也是递归的含义规定的。

  代码很简练,但是需要注意的是,递归算法是一种自身调用自身的算法,随着递归深度的增加,工作栈所需要的空间增大,所以不适用于消耗内存过大的内容,且递归调用时的辅助操作增多,因此,递归算法的运行效率较低。

时间: 2024-10-07 10:35:58

递归解决汉诺塔问题的相关文章

Java使用递归法解决汉诺塔问题的代码示例_java

汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A.B.C,A座上有n个盘子,盘子大小不等,大的在下,小的在上(如图). 有一个和尚想把这n个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上.在移动过程中可以利用B座,要求打印移动的步骤.如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C. 如果有2个盘子,可以先将盘子1上的盘子2移动到B:将盘子1移动到c:将盘子2移动到c.这说明了:可以借助B将2个盘子从A移动到C,当然,

【Python学习】Python解决汉诺塔问题

参考文章:http://www.cnblogs.com/dmego/p/5965835.html 一句话:学程序不是目的,理解就好:写代码也不是必然,省事最好:拿也好,查也好,解决问题就好! 信息时代不用信息就是罪过,直接抄不加理解与应用,就不是自己的,下次遇到还是不会,或许其中的某一个细节就能够用于各个问题的解决,共勉 学习一个东西总会遇到一些经典的问题,学习Python第二天尝试看一下汉诺塔问题,还是百度,看看解题思路,纯粹是重温初中课堂,越活越回去了  汉诺塔的图解递归算法 一.起源: 汉

C语言递归实现汉诺塔算法

汉诺塔的递归实现算法,将A中的圆盘借助B圆盘完全移动到C圆盘上, 每次只能移动一个圆盘,并且每次移动时大盘不能放在小盘上面 递归函数的伪算法为如下: if(n == 1) 直接将A柱子上的圆盘从A移动到C else 先将A柱子上的n-1个圆盘借助C柱子移动到B柱子上 直接将A柱子上的第n个圆盘移动到C柱子上 最后将B柱子上的n-1个圆盘借助A柱子移动到C柱子上 该递归算法的时间复杂度为O(2的n次方),当有n个圆盘时,需要移动圆盘2的n次方-1次 操作系统:ubuntu 编译软件:gcc 结果截

使用python实现递归版汉诺塔示例(汉诺塔递归算法)_python

利用python实现的汉诺塔.带有图形演示 复制代码 代码如下: from time import sleep def disp_sym(num, sym):        print(sym*num, end='') #recusiondef hanoi(a, b, c, n, tray_num): if n == 1:  move_tray(a, c)  disp(tray_num)  sleep(0.7)  else:  hanoi(a, c, b, n-1, tray_num)  mov

用javascript编制一个递归算法来解决汉诺塔问题

传说某间寺院有三根柱子,在创世之初,第一根柱子串有64个金盘,盘的尺寸由下到上一个比一个小.寺院里的僧侣依照一个古老的预言,每天移动一个盘:大盘不能叠在小盘上面,预言说盘子全部移动到到第三根柱子时,世界就会灭亡. 最少移动步数是随着盘子的个数呈指数增长(2^n-1)的.对指数增长有概念的同学应该能够看出移动64个盘子所需的步数是个天文数字,即使僧侣们每秒可完成一个盘子的移动,也需要5846亿年才能完成,整个宇宙现在也不过137亿年.这个世界灭亡传说的本意大概是在祝福世界不要灭亡吧. 在<猩球崛起

c#汉诺塔的递归算法与解析_C#教程

从左到右 A  B  C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱, 期间只有一个原则: 大盘子只能在小盘子的下面. 如果有3个盘子, 大中小号, 越小的越在上面, 从上面给盘子按顺序编号 1(小),2(中),3(大), 后面的原理解析引用这里的编号. 小时候玩过这个游戏, 基本上玩到第7个,第8个就很没有耐心玩了,并且操作的动作都几乎相同觉得无聊.  后来学习编程, 认识到递归, 用递归解决汉诺塔的算法也是我除了简单的排序算法后学习到的第一种算法. 至于递归,简单来说

c语言汉诺塔-汉诺塔可以用递归吗 不找规律的话

问题描述 汉诺塔可以用递归吗 不找规律的话 汉诺塔可以用递归吗 不找规律的话 求大神指点 递归应该怎么用才能解决汉诺塔 谢谢了 解决方案 汉诺塔本来就应该用递归,不用递归反倒麻烦,需要用堆栈模拟.http://blog.csdn.net/kkkkkxiaofei/article/details/8333644 解决方案二: #include<stdio.h> void move(int n,char a,char b,char c) { if(n==1) printf("t%c-&g

python实现汉诺塔方法汇总_python

学习python遇到的第一个问题:汉诺塔问题的实现.首先是不知道什么是汉诺塔问题,然后是不知道怎么实现.于是百度了下,结果如下: 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘 方法一: def move(n,a,b,c) # n=2 if n==1 :

JavaScript汉诺塔问题解决方法_javascript技巧

本文实例讲述了JavaScript汉诺塔问题解决方法.分享给大家供大家参考.具体实现方法如下: <script language="javascript"> var han=function (disc,src,aux,dst){ if(disc>0){ han(disc-1,src,dst,aux); document.writeln("move disc "+disc+" from "+src+" to "