Python Basic - 递规(recursion)

递归的作用

一个问题很大,很难解决,问题的复杂性和求解难度是随着规模不断的增大而变大的,在求解此类问题时可通过逐步缩小规模来简化求解难度。就像剥洋葱一样,我的目的是要知道洋葱有多少层,有几种办法?我能想到的有两种,一是直接拿刀切开,数横截面。这种办法既然需要刀,那肯定需要借助其它工具来实现;还有一种方法就是一层一层剥,剥一层就少一层,最终能把洋葱全部剥完,就知道多少层了。

递归的定义

一个函数直接或者间接的调用自己的函数就叫递规函数

递规的条件

  1. 每递规一次,问题的规模就需要缩小一点,或者说需要离我们的目标更近一点。
  2. 问题到最小规模的时候需要有终止递归的条件

递归的缺点

  1. 能用递归实现的,用循环一般都能实现
  2. 递归效率较低,每一轮递归都是将代码进行压栈(入栈,数据结构中栈相关章节)操作,递归层次过多会导致栈溢出,压栈压完后,再出栈,每出一次栈栈的深度就会少一层。一般栈都是有上限的,所以不可能无限次压栈。
  3. 占用内存比循环大,循环几乎不占用占用空间,占用空间的都是数据。

递规与循环的关系

递规示例

示例一:阶乘

所谓阶乘,一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,数学中阶乘的符号是“!”,如3!=3*2*1,5!=5*4*3*2*1。

使用循环完成阶乘

def factorial(x):
    amass = 1
    for i in range(1,x+1):
        amass *= i
    return amass

print(factorial(5))
print(factorial(10))

"""
120
3628800
"""

使用递归完成阶乘

如果数大于等于2,就使用此轮递归的值乘 上比 自己规模小1的函数,

  • 5!= 5*4*3*2*1 阶乘的表达式
  • 5! = 5*4! 所以5的阶乘=5*4的阶乘
  • 5!= 5*4*3! 5的阶乘=5*4*3的阶乘,
  • 范围依次在缩小,当x 小于2时,直接返回为1,这是一个退出递规的条件
  • 依次类推,代码如下:
def factorial(x):
    if x >= 2:
        return x * factorial(x-1)
    else:
        return 1

print(factorial(5))
print(factorial(10))
print(factorial(15))
"""
120
3628800
1307674368000
"""

示例二:斐波拉契数列

斐波拉契数列百度百科

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……
第一项为1
第二项为1
从第三项开始,每个数都是前两个数之和

本实验的思路是生成一个列表,让调用函数的时候输入的实参为数字的时候就生成列表中几个元素。

循环实现

def Fibonacci(x):
    if x == 1:
        sequence = [1]
        return sequence
    elif x == 2:
        sequence = [1,1]
        return sequence
    elif x > 2:
        sequence = [1,1]
        for i in range(2,x):
            sequence.append(sequence[i-1] + sequence[i-2])
        return sequence
    elif x <= 0:
        return "input error,number must grather than 0"

print(Fibonacci(5))
print(Fibonacci(10))
print(Fibonacci(20))
print(Fibonacci(1))
print(Fibonacci(2))
print(Fibonacci(-1))

"""
[1, 1, 2, 3, 5]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
[1]
[1, 1]
input error,number must grather than 0
"""

递归实现

使用递归返回相应下标的数列的值,使用循环求出每个下标的值后放入到列表中,我暂时还没找到更好的方法,后续发现后再行改善

def Fibonacci(x):
    sequence = []
    def subFibonacci(y):
        if y == 1:
            return 1
        elif y == 2:
            return 1
        elif y > 2:
            return subFibonacci(y-1)+subFibonacci(y-2)
    for i in range(1,x+1):
        sequence.append(subFibonacci(i))
    return sequence


print(Fibonacci(5))
print(Fibonacci(10))
print(Fibonacci(20))
print(Fibonacci(1))
print(Fibonacci(2))
print(Fibonacci(-1))

"""
[1, 1, 2, 3, 5]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
[1]
[1, 1]
[]
"""

汉诺塔请点击此链接–我的另外一篇博文

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值