python学习-递归(阶乘、汉诺塔)

求阶乘(循环)

如果需要求一个数的阶乘,可能刚开始脑海里面冒出来的是循环计算,下面看看循环如何实现:

def recur1(num):
    rst1 = 1
    for item in range(1, num + 1):
        print(item)
        rst1 = rst1 * item
    print(rst1)
    return rst1


recur1(5)

为了体现变化,我这里把每个值都打印出来了。
运行结果:
在这里插入图片描述
1 * 2 * 3 * 4 * 5 = 120

求阶乘(递归)

如果不使用循环,我们可以使用递归的方式,下面解释一下递归的定义:
递归算法(英语:recursion algorithm)在计算机科学中指一种通过重复而将问题分解为同类的子问题来解决问题的方法。
使用递归式方法可以解决很多的计算机科学的问题,它是计算机科学中十分重要的概念。绝大多数编程语言支持函数的自调用,因此在这些语言中函数可以通过调用自身来进行递归。
计算理论可以证明递归的作用完全可以取代循环,在很多函数编程语言(如Scheme)中习惯用递归来实现循环。
这段话摘抄自百度词条,也是为了让自己更清楚递归的含义。
下面来看实现:

def recur2(num):
    if num == 1:
        return num
    return num * recur2(num - 1)


print(recur2(5))

运行结果:120

在示例中我们能看到,代码比使用循环简洁了不少,而且意义更明了。
下面这段话也要注意:
基线条件(base case)。基线条件是递归程序的最底层位置,在此位置时没有必要再进行操作,可以直接返回一个结果。
所有递归程序都必须至少拥有一个基线条件,而且必须确保它们最终会达到某个基线条件;否则,程序将永远运行下去,直到程序缺少内存或者栈空间。

推荐另一篇关于递归的文章,写得很详细,也很用心,如果我的博文有幸被你们看到,那可以去看看他的这篇:Python递归算法详解
写得很详细的,内容更丰富。

默认的Python有一个可用的递归深度的限制,以避免耗尽计算机中的内存。默认是1000。

当然递归的优点和缺点都是很明显的,从刚才推荐的这篇博文里面截了一张图,大家可以看看。
在这里插入图片描述

汉诺塔

有一座钻石宝塔A,其上有64个金蝶。所有碟子按从大到小的次序从塔底堆放至塔顶。紧挨着这座塔有另外两个钻石宝塔B和C。每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。把A上的碟子全部移到C上。
这个如果不用递归,实现起来,难度太大,毕竟次数太多了。
使用递归看着就会很简单了,上代码:
使用递归解决问题,首先需要化繁为简,简化步骤,明确要实现的功能。

def Hanoi(n, A, B, C) :
  if (n == 1) :
    move(A, c)   #表示只有一个碟子时,直接从A塔移动到C塔
  else :
    Hanoi(n - 1, A, C, B)  #将剩下的A塔上的n-1借助C塔移动到B塔
    move(A, C)              #将A上最后一个直接移动到C塔上
    Hanoi(n - 1, B, A, C)  #将B塔上的n-1个碟子借助A塔移动到C塔

这段代码就是对汉诺塔使用递归实现的一种解析,综合起来分成三步。
实现代码:

iBeg = 1


def move(iNum, frm, to):
    global iBeg
    # print("第%d步:将%d号盘子从%s -> %s" % (iBeg, iNum, frm, to))
    iBeg += 1


def hanoi(iNum, a, b, c):
    if iNum == 1:
        move(1, a, c)
    else:
        hanoi(iNum - 1, a, c, b)
        move(iNum, a, c)
        hanoi(iNum - 1, b, a, c)


iNum = int(input("请输入一个数字:"))
if isinstance(iNum, int):
    if 0 > iNum or iNum > 64:
        print("请输入一个0-64之间的整数!")
    else:
        hanoi(iNum, 'A', 'B', 'C')
        print("移动步数:", iBeg)
else:
    print("请输入一个整数!")

大家可以自己运行试试,move函数里面有个注释,如果运行数字比较小,10以内,那就可以放开注释,看看运行步骤。如果数字较大,还是直接运行吧。

如果大家电脑性能不太好,那还是不要尝试64个盘子的汉诺塔了,太耗时
本来想测试一下64个盘子要循环多少次,不过跑了一个小时还没跑出来。10,20都能很快跑出结果,30跑了几分钟,运行出结果了:
在这里插入图片描述

下面这张图是比较直观的一种方式,在ppt里面,插入这几个形状,然后自己挪动一下,从A按步骤,挪动到C,对这个思路就比较的清晰了。
在这里插入图片描述
还有一个斐波拉契数列,这个递归实现网上很多,我这里没有去自己实现,所以不贴代码了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值