在一個函數裏再調用這個函數自己,這種魔性的使用函數的方式就叫作遞歸。python
遞歸函數若是不受到外力的阻止會一直執行下去。每一次函數調用都會產生一個屬於它本身的名稱空間,若是一直調用下去,會形成名稱空間佔用太多內存。因而python爲了杜絕相似內存溢出現象,強制將遞歸層數控制在了998。算法
def func(): print(1) func() func() # 遞歸最大深度爲:998
由此能夠看出,未報錯以前能看到的最大數字就是997。997是python爲了程序的內存優化所設定的一個默認值,能夠經過一些手段修改:函數
# 修改遞歸的最大深度(儘可能不要改) import sys sys.setrecursionlimit(1000000) # 3221 def foo(n): print(n) n += 1 foo(n) foo(1)
能夠經過這種方式來修改遞歸的最大深度,剛剛將python容許的遞歸深度設置爲了10W,實際能夠達到的深度取決於計算機的性能。不推薦修改這個默認的遞歸深度,若是用997層遞歸都沒能解決的問題,要麼不適合遞歸解決,要麼代碼寫的太爛。
江湖流傳這樣一句話:人理解循環,神理解遞歸。
sys模塊:包含全部和python相關的設置和方法。
遞歸就是本身調用本身。
遞歸須要有一箇中止條件,若是沒有中止條件就會報錯。性能
6!優化
65432*1code
def fn(n): if n == 1:return 1 return n*fn(n-1) print(fn(6))
執行過程:
def fn(6):
return 6*fn(5)blog
def fn(5): return 5*fn(4) def fn(4): return 4*fn(3) def fn(3): return 3*fn(2) def fn(2): return 2*fn(1) def fn(1): return 1
小明是新來的同窗,麗麗問他多少歲了。排序
他說:我不告訴你,可是我比滔滔大兩歲。遞歸
滔滔說:我也不告訴你,我比曉曉大兩歲內存
曉曉說:我也不告訴你,我比小星大兩歲
小星也沒有告訴他說:我比小華大兩歲
最後小華說,我告訴你,我今年18歲了
知道小華的,就會知道小星的,知道小星的就會知道曉曉的,以此類推,就會知道小明的年齡。這個過程接近遞歸思想。
用序號表示:
age(5) = age(4)+2 age(4) = age(3) + 2 age(3) = age(2) + 2 age(2) = age(1) + 2 age(1) = 18
寫成代碼:
def age(n): if n == 1: return 18 else: return age(n - 1) + 2 ret = age(6) print(ret)
def cal(num): if num%2==0: #先判斷能不能整除 num=num//2 return cal(num) else: return num print(cal(8))
def func(num): print(num) if num==1: return if num%2==0: num=num//2 else: num=num*3+1 func(num) func(5)
# 人類的算法(靈活)
9999=99(100-1)=9900-99=9801
# 計算機的算法(死板)
99*99
計算一些比較複雜的問題,所採用的在空間上(內存裏)或者時間上(執行時間)更有優點的方法
# 排序 500W個數:快速排序、堆排序、冒泡排序
# 查找
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]
# 簡單版二分法 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 cal(l,num=66): length = len(l) mid = length//2 if num > l[mid]: l = l[mid+1:] cal(l,num) elif num < l[mid]: l = l[:mid] cal(l, num) else: print('找到了',l[mid],mid) cal(l,66) # 升級版二分法 def cal(l,num,start=0,end=None): # if end is None:end = len(l)-1 end = len(l)-1 if end is None else end if start <= end: mid = (end - start)//2 + start if l[mid] > num : return cal(l, num, start, mid-1) elif l[mid] < num: # 13 24 return cal(l,num,mid+1,end) else: return mid else: return None 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] print(cal(l,56))