递归介绍
递归就是在函数执行过程中调用自己
import sys
print(sys.getrecursionlimit())#最多1000次限制递归层次
sys.setrecursionlimit(1500)#改变递归层次
def recursion(n):
print(n)
recursion(n+1)
recursion(1)
递归与栈的关系
程序在执行900多次就出错,超过最大递归深度限制,
通俗讲 是因为每个函数在调用自己的帧时,还没有退出,多了肯定会导致内存崩溃
本质上讲 在计算机中,函数调用是通过站(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧,由于栈的大小不是无限的,所以,递归调用的次数过多,栈就会溢出
递归的作用
10/2 整除 除到0为止
def calc(n):
v = n/2
print(v)
if v == 0:
return 'done'
calc(v)
print(v)#在打印一个v
calc(10)
#结果
5
2
1
0
1
2
5
每一个递归都要有截止条件
每一次进入更深一层递归时,问题规模相比上次递归都应有所减少
递归的执行效率不太高,递归层次过多会导致栈溢出
#阶乘 n!=n*(n-1)!
def factorial(n):
if n==1:
return 1
return n*factorial(n-1)
print(factorial(4))
尾递归优化
在调用下一层的同时自己就退出(阶乘不是尾递归)
并不是在所有语言都支持 python并没有做尾递归优化
def cal(n):
print(n)
return cal(n+1)
cal(1)
应用场景并不多
练习:
二分查找
def binary_search(lis, left, right, num):
if left > right: #递归结束条件
return -1
mid = (left + right) // 2
if num < lis[mid]:
right = mid -1
elif num > lis[mid]:
left = mid + 1
else:
return mid
return binary_search(lis, left, right, num)
#这里之所以会有return是因为必须要接收值,不然返回None
#回溯到最后一层的时候,如果没有return,那么将会返回None
lis = [11, 32, 51, 21, 42, 9, 5, 6, 7, 8]
print(lis)
lis.sort()
print(lis)
while 1:
num = int(input('输入要查找的数:'))
res = binary_search(lis, 0, len(lis)-1,num)
print(res)
if res == -1:
print('未找到!')
else:
print('找到!')