python实现经典算法(1):汉诺塔

时间:2021-08-04 09:54:35

1. 递归过程

递归算法,把大规模问题分解成容易解决而且求解方法相同的子问题,一般用递归函数实现,递归函数就是不断调用自身的函数。举个例子:

python实现经典算法(1):汉诺塔
俄罗斯套娃(应该都玩过,里面最小的那个不能打开,其他都能打开。从最小的娃娃开始,用稍大的那个娃娃套着,直至最大的一个套住所有的娃娃)。
现在有如图俄罗斯套娃,已经按正确的方法套好,里面最小的那个娃娃背上写了一个密码。现在需要求解的问题是得到那个密码,并且得到密码后要把这套俄罗斯娃娃按正确的方法套好。
那么做法应该是:一层一层地打开娃娃,直到看到最小的娃娃之后获取密码,然后一个一个把娃娃合上。也就是,分别按顺序对每一个娃娃进行打开的操作,直至打开到小娃娃,查看密码,然后再进行依次闭合娃娃的操作。
这就是一个递归过程。而这个递归函数就是打开闭合娃娃,判断里面的娃娃是否是最小的那个,如果是,获取密码;如果不是,打开下一个娃娃,并且最后关闭当前娃娃。

2. 递归过程求解

一个问题能否用递归求解,要看这个问题能不能逐层分解成一个个规模依次变小的小问题,同时有能够进行判断的下限(就是不能再小的子问题)。

而确定能够用递归过程求解之后,关于求解步骤,可以直接分析最小的子问题和比最小子问题“大1”的子问题。还需要知道的有:最小子问题的判断依据以及处理步骤、如何递归调用自身。拿汉诺塔问题举例:(借助B柱,将A柱上的n块盘子移动到C柱)

python实现经典算法(1):汉诺塔

最小的子问题就是:将一块盘子从A移动到C柱“大1”的子问题是:将两块盘子从A移动到C柱,不妨在草稿纸上画个图,显然有三个步骤:

  • 将最上面的盘子从A移动到B
  • 将A下面的盘子从A移动到C
  • 将B上的盘子移动到C

而程序调用自身则是逐次对(n-1)个盘子进行同样的操作就可以解决n个盘子移动的问题。
只需以上三步分析就能得到这个递归程序的全部求解过程。

3. 汉诺塔的python代码

n = int(input("输入初始化时A塔上盘子的个数n:\n"))  

def move( n , A , B ,C ):
if n == 1 :
print( "%s is moved to %s" %(A ,C) )
else :
move( n-1 , A , C , B )
move( 1 , A , B , C )
move( 1 , B , A , C )

move( n ,'A' , 'B' , 'C')

如果还是不理解的话,自己动手写一个递归程序最能加深理解。经典的递归问题有:Fibonacci数列、扫雷小游戏。

4. 题外话

传说古老印度在一个圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片圣庙,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片,一次只移动一片,不管在哪根针上,小片必在大片上面。当所有的金片都从梵天穿好的那根针上移到另外一概针上时,世界就将在一声霹雳中消灭,梵塔、庙宇和众生都将同归于尽。n个盘子最少需要移动2^n-1,如果一秒钟移动一次,计算出来需要5800多亿年,那时候,地球还存在吗?这样看来,这个毁灭论倒是有一定道理的。

转载:http://blog.csdn.net/u014496330/article/details/44620867