定义
函数之间是可以相互调用的,而递归就是函数调用自身的过程。
>>> def funA():
print("Love")
>>> def funB():
funA()
>>> funB() //函数的间接调用
Love
>>> def func(n):
if n>0: //递归调用一定要有结束条件!!!
print("I Love Python")
n-=1
func(n) //递归,函数调用自身
>>> func(5)
I Love Python
I Love Python
I Love Python
I Love Python
I Love Python
递归的两个特点(重中之重!!!)
- 调用自身
- 结束条件
递归的应用
能够用递归实现的功能都能够用循环迭代来实现
求一个正整数的阶乘
>>> def factIter(n): //使用循环迭代实现一个正整数的阶乘
result=n
for i in range(1,n):
result *= i
return result
>>> factIter(5)
120
>>> factIter(10)
3628800
>>> def factRecur(n): //使用递归实现一个正整数的阶乘
if n==1:
return 1
else:
return n*factRecur(n-1)
>>> factRecur(5)
120
用递归实现斐波那契数列
起源
假设有一对兔子在两个月大的时候才有繁殖能力,接下来每个月都生出一对兔子宝宝,如果假设所有的兔子都不会老去,那么一年后会繁殖出多少对可爱的兔子来呢?
如果在年初种下一对兔子,就可以在年底收获144对美味的兔头,
代码的具体实现如下
>>> def fibIter(n): //用循环迭代的方式实现斐波那契数列
a=1
b=1
c=1
while n>2:
c=a+b
a=b
b=c
n-=1
return c
>>> fibIter(12)
144
>>> def fibRecur(n): //用递归的方式实现斐波那契数列
if n==1 or n==2:
return 1
else:
return fibRecur(n-1)+fibRecur(n-2)
>>> fibRecur(12)
144
>>>
Q:递归的效率问题
用其他方式实现斐波那契数列
用闭包实现斐波那契数列
(待更新,,,求大神评论区提供一下)
用生成器实现斐波那契数列
- 传参
>>> def fibs(n):
a=0
b=1
while n>0:
a,b=b,a+b
n-=1
yield a
>>> list(fibs(12))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
- 不传参
>>> def fib():
a=0
b=1
while True:
a,b=b,a+b
yield a
>>> for i in fib():
if i<100:
print(i)
else:
break
1
1
2
3
5
8
13
21
34
55
89
用迭代器实现斐波那契数列
- 传参
>>> class Fib:
def __init__(self,n=20):
self.a=0
self.b=1
self.n=n
def __iter__(self):
return self
def __next__(self):
self.a,self.b=self.b,self.a+self.b
if self.a>self.n:
raise StopIteration
return self.a
执行结果
>>> fibd=Fib()
>>> for i in fibd:
print(i)
1
1
2
3
5
8
13
>>> f=Fib(n=100)
>>> for i in f:
print(i)
1
1
2
3
5
8
13
21
34
55
89
- 无参
class Fibs:
def __init__(self):
self.a=0
self.b=1
def __iter__(self):
return self
def __next__(self):
self.a,self.b=self.b, self.a+self.b
return self.a
>>> f=Fibs()
>>> for i in f:
if i<20:
print(i)
else:
break
1
2
3
5
8
13
用递归实现汉诺塔
起源
汉诺塔在1883年时由法国数学家卢卡斯发明的,该数学问题与一个印度传说有关,据说在世界中心贝拿勒斯的圣庙里有一块黄铜板,上面插着三根宝针,印度教主神梵天在创造世界的时候,在其中的一根针上从上往下穿好了由大到小的64枚金片,这就是汉诺塔的原型。有一个僧侣没日没夜的移动,当所有的金片都移动到另外一根针上的时,世界就会在一声霹雳中消灭,梵塔和众生也都将同归于尽。
规则
- 一次只能移动一枚金片
- 无论在哪根针上,小片必须在大片的上面
抽象为数学问题
如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数
解:
- n 为1
第1次 1号盘 A---->C sum = 1 次 - n 为2
第1次 1号盘 A---->B
第2次 2号盘 A---->C
第3次 1号盘 B---->C sum = 3 次
- n 为 3
第1次 1号盘 A---->C
第2次 2号盘 A---->B
第3次 1号盘 C---->B
第4次 3号盘 A---->C
第5次 1号盘 B---->A
第6次 2号盘 B---->C
第7次 1号盘 A---->C sum = 7 次
规律:
1个圆盘的次数 2的1次方减1
2个圆盘的次数 2的2次方减1
3个圆盘的次数 2的3次方减1
。 。 。 。 。
n个圆盘的次数 2的n次方减1
算法步骤分析:
实现这个算法可以简单分为三个步骤:
- 把n-1个盘子由A 移到 B;
- 把第n个盘子由 A移到 C;
- 把n-1个盘子由B 移到 C;
从这里入手,在加上上面数学问题解法的分析,可以发现
- 把A上n-1个盘子通过借助辅助塔(C塔)移到了B上,
- 把最大的一个盘子由A移到C上去;
- 把B上n-1个盘子通过借助辅助塔(A塔)移到了C上;
代码实现如下:
def hanoi(n,x,y,z):
if n== 1:
print(x,'-->',z) # 只有一层,直接将x移动到z
else:
hanoi(n-1,x,z,y) # 将x上的n-1个圆盘移动到y
print(x,'-->',z) # 将最底下的圆盘从x移动z
hanoi(n-1,y,x,z) # 将y行的n-1个圆盘移动到z
n=int(input("请输入汉诺塔的层数:"))
hanoi(n,'A','B','C')
执行结果如下:
参考:
Python实现斐波那契数列.