软件测试学习 之 Python 递归与汉诺塔

12 篇文章 0 订阅
1 篇文章 0 订阅

 递归

在数学与计算机科学中,是指在函数的定义中使用函数自身的方法,绝大多数编程语言支持函数的自调用

递归的强大之处在于它允许用户用有限的语句描述无限的对象。

因此,在计算机科学中,递归可以被用来描述无限步的运算,尽管描述运算的程序是有限的。

递归的两个必要条件

 1.要有递推关系
 2.要有临界

下面是用递归实现阶乘的代码

def factorial(n):
    """
    求阶乘
    :param n:最大值
    :return:阶乘
    """
    if n is 1:
        return n
    else:
        # 这里调用本身的函数
        return n * factorial(n - 1)


print("1*2*3*4*...*100=%E" % factorial(100))

执行结果如下:
1*2*3*4*...*100=9.332622E+157

汉诺塔

汉诺塔算法介绍

其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n – 1(有兴趣的可以自己证明试试看)。后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:
若n为偶数,按顺时针方向依次摆放 A B C;
若n为奇数,按顺时针方向依次摆放 A C B。

具体操作如下:
(1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子
         当n为偶数时,若圆盘1在柱子A,A→B;若圆盘1在柱子B,则B→C;若圆盘1在柱子C,C→A
         当n为奇数时,若圆盘1在柱子A,A→C;若圆盘1在柱子C,则C→B;若圆盘1在柱子B,B→A
(2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。
          有一根柱子为空时,非空柱子上的圆盘移动到空柱子上,
          两根柱子都非空时,移动较小的圆盘到另一根柱子上。
(3)反复进行(1)、(2)操作,最后就能按规定完成汉诺塔的移动。

所以结果非常简单,就是按照移动规则向一个方向移动金片:
如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C


以上只是在实际移动时得出的技巧,真正的算法不必如此复杂,大致思路如下:
首先,将A柱子上n-1个盘子通过C柱子移动到B柱子上(相当于从A到B的汉罗塔)
接着,将A柱子上第n个盘子直接移动到C柱子上
最后,将B柱子上n-1个盘子通过A移动到C柱子上(相当于从B到C的汉罗塔)
除了中间一步之外,其余两步都是汉诺塔的递归操作,如此层层深入,直到最后只剩一个盘子为止

Python实现代码如下:

# 定义全局变量count,用来记录移动次数
count = 0


def hanoi(n, a, b, c):
    """
    # Python递归实现汉诺塔
    :param n: A柱上圆盘的个数
    :param a: A柱子
    :param b: B柱子
    :param c: C柱子
    :return:
    """
    global count
    if n == 1:
        count += 1
        print('移动第', count, '次', a, '-->', c)
    else:
        # 1.把A柱上n-1个圆盘通过C柱移动到B柱上
        hanoi(n - 1, a, c, b)
        # 2.把A柱上最大的移动到C柱子上
        hanoi(1, a, b, c)
        # 3.把B柱子上n-1个圆盘通过A柱移动到C柱子上
        hanoi(n - 1, b, a, c)

执行结果如下:
移动第 1 次 A --> C
移动第 2 次 A --> B
移动第 3 次 C --> B
移动第 4 次 A --> C
移动第 5 次 B --> A
移动第 6 次 B --> C
移动第 7 次 A --> C

以上内容部分参考如下博文修改整理

作者:风在人舟
出处:博客园
博文:python递归详解+汉诺塔小案例

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值