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

1. 递归过程

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

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

2. 递归过程求解

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

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

这里写图片描述

最小的子问题就是:将一块盘子从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(n-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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值