python递归实现二分查找_python之路18--之递归与使用递归实现二分查找算法

认识递归

1、什么是递归函数:

在自身函数里调用自己,就是递归函数,python系统默认最大递归次数为998次,超过了这个次数会报如下错误(RecursionError: maximum recursion depth exceeded while calling a Python object),写递归时一定要写结束条件!!

1.1、递归的返回值:

不要只看到return就认为已经返回了,要看返回操作是在递归到几层的时候发生的,然后返回给了谁

如果不是返回给外层函数,调用者就接收不到

需要再分析,看如何把结果返回回来

2、如何修改默认递归得次数:

不建议修改,如果递归次数太多就不适合用递归来解决

import sys

sys.setrecursionlimit(10000)

3、递归得优缺点:

优点:会让代码变简单

缺点:占内存

一个递归计算年龄的例子及递归得运行过程

需求:

求欧阳多大了

已知:欧阳比张三大两岁,

张三比李四大两岁,

李四比二麻子大两岁

二麻子今年40了

递归得代码:求欧阳今年多大了:

defage(n):if n == 4:return 40

elif n > 0 and n < 4:return age(n+1)+2

print(age(1)) #最终计算结果:46

上面得递归代码运行得过程:

第一次递归,执行函数时将1当实参传进来了def age(1):if 1 == 4:return 40

elif 1 > 0 and 1 < 4:return age(1+1)+2 #age(2+2 #44+2==46最终结果为:46

def age(2):if 2 == 4:return 40

elif 2 > 0 and 2 < 4:return age(2+1)+2 #age(3)+2 #42+2==44

def age(3):if 3 == 4:return 40

elif 3 > 0 and 3 < 4:return age(3+1)+2 #age(4)+2 #40+2==42

def age(4):if 4 == 4: #n==4时

return 40 #返回40

elif 3 > 0 and 3 < 4: #不符合这里得条件,一下代码不执行

return age(3+1)+2

画图说明执行过程:

1436685-20180825100558419-983009174.png

一个递归计算斐波那契数列的例子及递归的过程

斐波那契数列说明(第一位和第二位都是1,以后的每个数字是前两个数字相加的合):1,1,2,3,5,8,13,21,34,55,89

1、使用双调用的形式计算斐波那契数列

deffib(n):if n == 1 or n == 2:return 1

return fib(n-1) +fib(n-2)print(fib(5))

1.1、递归方式

第一次递归的过程def fib(5):if n == 1 or n == 2: #向下递归 #向上预算结果

return 1

return fib(n-1) +fib(n-2) #fib(5-1) + fib(5-2) #3+2=5

print(fib(5)) #结果为5

第二次递归得过程def fib(4):if n == 1 or n == 2:return 1

return fib(n-1) +fib(n-2) #fib(4-1) + fib(4-2) #2+1=3

print(fib(4)) #结果为:3

def fib(3):if n == 1 or n == 2:return 1

return fib(n-1) +fib(n-2) #fib(3-1) + fib(3-2) #1+1=2

print(fib(3)) #结果为:2

第三次递归的过程def fib(3):if n == 1 or n == 2:return 1

return fib(n-1) +fib(n-2) #fib(3-1) + fib(3-2)

print(fib(3))def fib(2):if n == 1 or n == 2:return 1 #返回1

return fib(n-1) +fib(n-2)print(fib(2))def fib(1):if n == 1 or n == 2:return 1 #返回1

return fib(n-1) +fib(n-2)print(fib(1))

说明:双递归的方式计算斐波那契数列效率很慢,因为递归里设计到两次函数调用,每个函数每次调用都要重新计算一下,具体看下图详解

1436685-20180825125817417-1773713457.png

2、使用但调用的形式计算斐波那契数列

#一次调用计算斐波那契数列

deffib(n):if n == 2:return 1,1

else:

a,b= fib(n-1)print(a,b)return b,a+bprint(fib(4)) #结果为前一个数字和计算结果(不完美)

#修改后(只显示计算出的斐波那契数列 完美的)

def fib(n,l =[0]):

l[0]+=1

if n == 1 or n == 2:

l[0]-= 1

return 1,1

else:

a,b= fib(n-1)

l[0]-= 1

if l[0] ==0:return a+breturn b,a+bprint(fib(4))

2.1、递归过程说明:

deffib(n):if n == 2:return 1,1

else:

a,b= fib(n-1)print(a,b)return b,a+bprint(fib(4)) #最终结果为(2,3)

#第一次递归

def fib(4):if 4 == 2: #0、条件不成立

return 1,1

else:

a,b= fib(4-1) #1、4-1=3 #8、a=1,b=2

return b,a+b #9、返回值2,3

print(fib(4))#第二次递归

def fib(4):if 4 == 2: #2、条件不成立

return 1,1

else:

a,b= fib(4-1) #3、3-1=2 #6、a=1,b=1

return b,a+b #7、返回值1,2

print(fib(4))#第三次递归

def fib(4):if 4 == 2: #4、条件成立

return 1,1 #5、返回1,1

else:

a,b= fib(4-1)return b,a+bprint(fib(4))

算法

什么叫算法:计算的方法:人脑复杂,计算机简单

查找:找数据

排序:找最短路径

现在学习的算法都是过去式

了解基础的算法才能创造出更好的算法

不是所有的事情都能套用现成的方法解决的

有些时候用到学过的算法知识来解决新的问题

二分查找算法

二分查找算法,必须处理有序的列表

使用递归实现二分查找算法:

l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]def find(l,aim,start = 0,end =None):

end= len(l) if end is None elseend

mid_index= (end - start) // 2 +startif start <=end:if l[mid_index] aim:return find(l,aim,start=start,end=mid_index-1)else:return print('找到了,index为:%s'%mid_index,)else:return '找不到这个值...'ret= find(l,44)print(ret)

递归实现的过程

#第一次递归

def find(l,aim,start = 0,end =None):

end= len(l) if end is None else end #end = len(l) -->25

mid_index = (end - start) // 2 + start #计算中间值 25 // 2 == 12 + 0 == 12

if l[mid_index] < aim: #12和目标作比较,12 < 44

find(l,aim,start = mid_index+1,end=end) #find (l,44,start=13,end=24)

elif l[mid_index] >aim:

find(l,aim,start=start,end=mid_index-1)else:print('找到了',mid_index,aim)

find(l,44)#第二次递归

def find(l,aim,start = 0,end = None): #find(l,44,start = 13,end = 24)

end = len(l) if end is None else end #end 不等于空,所以end = 24

mid_index = (end - start) // 2 + start #计算中间值 (24 - 13) // 2 == 5 + 13 == 18

if l[mid_index] < aim: #18和目标作比较,l[18] == 67,67和44比较

find(l,aim,start = mid_index+1,end=end)elif l[mid_index] > aim: #67 > 44

find(l,aim,start=start,end=mid_index-1) #find (l,44,start=13,end=18 - 1)

else:print('找到了',mid_index,aim)#第三次递归

def find(l,aim,start = 0,end = None): #find(l,44,start = 13,end = 17)

end = len(l) if end is None else end #end 不等于空,所以end = 17

mid_index = (end - start) // 2 + start #计算中间值 (17 - 13) // 2 == 2 + 13 == 15

if l[mid_index] < aim: #15和目标作比较,l[15] == 55,55和44比较

find(l,aim,start = mid_index+1,end=end)elif l[mid_index] > aim: #55 > 44

find(l,aim,start=start,end=mid_index-1) #find (l,44,start=13,end=15 - 1)

else:print('找到了',mid_index,aim)#第四次递归

def find(l,aim,start = 0,end = None): #find(l,44,start = 13,end = 14)

end = len(l) if end is None else end #end 不等于空,所以end = 14

mid_index = (end - start) // 2 + start #计算中间值 (14 - 13) // 2 == 0 + 13 == 13

if l[mid_index] < aim: #13和目标作比较,l[13] == 42,42和44比较,42 <44

find(l,aim,start = mid_index+1,end=end) #find (l,44,start=14,end=14)

elif l[mid_index] >aim:

find(l,aim,start=start,end=mid_index-1)else:print('找到了',mid_index,aim)#第五次递归

def find(l,aim,start = 0,end = None): #find(l,44,start = 14,end = 14)

end = len(l) if end is None else end #end 不等于空,所以end = 14

mid_index = (end - start) // 2 + start #计算中间值 (14 - 14) // 2 == 0 + 13 == 13

if l[mid_index] < aim: #13和目标作比较,l[13] == 42,42和44比较,42 <44

find(l,aim,start = mid_index+1,end=end) #find (l,44,start=15,end=14) #start大于end时预示着找不到了

elif l[mid_index] >aim:

find(l,aim,start=start,end=mid_index-1)else:print('找到了',mid_index,aim)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值