今日内容大纲
1.递归函数
2.二分查找算法
1.递归函数
定义:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
递归的最大深度:998
正如你们刚刚看到的,递归函数如果不受到外力的阻止会一直执行下去。但是我们之前已经说过关于函数调用的问题,每一次函数调用都
会产生一个属于它自己的名称空间,如果一直调用下去,就会造成名称空间占用太多内存的问题,于是python为了杜绝此类现象,强制的
将递归层数控制在了997。
例:验证递归最大深度
def func(n):
n += 1
print(n)
return func(n)
func(0)
例:求n阶乘
def fact(n):
n = int(n)
if n == 1: return 1
elif n <= 0:return "n只能大于0"
else: return n * fact(n - 1) #n = 3 #3 * fact(2) # 3 * 2 * fact(1) # 3 * 2 * 1
print(fact(3.1))
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,
栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数
也是可以的。尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把
尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
例:升级版阶乘
def fact(n):
return fact_iter(n, 1)
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
print(fact(4))
2.二分查找算法
def binary_search(li,aim,start=0,end=None): # 第一次:l1 = [1, 3, 5, 7, 8, 10, 11],aim = 8,start = 0, end = 7,mid_index = 3
# 第二次:l1 = [1, 3, 5, 7, 8, 10, 11],aim = 8,start = 4, end = 7,mid_index = 5
# 第三次:l1 = [1, 3, 5, 7, 8, 10, 11],aim = 8,start = 4, end = 5,mid_index = 4
#此时 aim = li[mid_index] return mid_index = 4
end = len(li) if end is None else end
mid_index = (end - start) // 2 + start
if start <= end:
if aim > li[mid_index]:
return binary_search(li, aim, start=mid_index+1, end=end)
elif aim < li[mid_index]:
return binary_search(li, aim, start=start, end = mid_index)
elif aim == li[mid_index]:
return mid_index
else:
return None
l1 = [1, 3, 5, 7, 8, 10, 11]
print(binary_search(l1, 8))