递归的作用
一个问题很大,很难解决,问题的复杂性和求解难度是随着规模不断的增大而变大的,在求解此类问题时可通过逐步缩小规模来简化求解难度。就像剥洋葱一样,我的目的是要知道洋葱有多少层,有几种办法?我能想到的有两种,一是直接拿刀切开,数横截面。这种办法既然需要刀,那肯定需要借助其它工具来实现;还有一种方法就是一层一层剥,剥一层就少一层,最终能把洋葱全部剥完,就知道多少层了。
递归的定义
一个函数直接或者间接的调用自己的函数就叫递规函数
递规的条件
- 每递规一次,问题的规模就需要缩小一点,或者说需要离我们的目标更近一点。
- 问题到最小规模的时候需要有终止递归的条件
递归的缺点
- 能用递归实现的,用循环一般都能实现
- 递归效率较低,每一轮递归都是将代码进行压栈(入栈,数据结构中栈相关章节)操作,递归层次过多会导致栈溢出,压栈压完后,再出栈,每出一次栈栈的深度就会少一层。一般栈都是有上限的,所以不可能无限次压栈。
- 占用内存比循环大,循环几乎不占用占用空间,占用空间的都是数据。
递规与循环的关系
递规示例
示例一:阶乘
所谓阶乘,一个正整数的阶乘(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]
[]
"""