python 之 遞歸
阿新 • • 發佈:2018-05-25
沒有 解決問題 每次 參數 fff arc 例子 calc block
終於來到了這裏,這是一座山,山那邊都是神仙
定義:在一個函數裏調用函數本身
最好的例子就是,求階乘
def factorial(n): if n == 1: return 1 elif n > 1: return n*factorial(n-1) while True: n = input(‘n>>‘) n = int(n) print(factorial(n))
遞歸最大層數
上面金典的例子運行的很成功
下面再來一個,是一個古老的故事,說,從前有個山,山裏有座廟,廟裏老和尚講故事, 講的什麽呢? 從前有個山,山裏有座廟,廟裏老和尚講故事, 講的什麽呢? 從前有個山,山裏有座廟,廟裏老和尚講故事, 講的什麽呢? 從前有個山,山裏有座廟,廟裏老和尚講故事, 講的什麽呢? 從前有個山,山裏有座廟,廟裏老和尚講故事, 講的什麽呢?
我們用代碼開實現一下
def story(): s = """ 從前有個山,山裏有座廟,廟裏老和尚講故事, 講的什麽呢? """ print(s) while True: story()
你運行了嗎?
shit,他報錯了,但是這個故事講的很完美。
RecursionError: maximum recursion depth exceeded while calling a Python object
這個錯誤是說,這個程序運行的代碼,超過了最大遞歸層數。
正如我們看到的,如果沒有外界阻力,它會一直運行下去
# 添加參數,設置停止條件 def calc(n, count): print(n, count) if count < 5: return calc(n/2, count+1) else: return n print(calc(188,0))
因為每一次函數調用都會產生一個屬於它自己的名稱空間,如果一直調用下去,就會造成名稱空間占用太多內存的問題,直到內存被占滿,然後死機。
所以限制了他的最大遞歸層數,一般就是999層,
當然這個數字是可以修改的,修改方法很冷門,一般也不會有人去修改它,
因為如果遞歸了999層都沒有解決問題,那麽,你該想想是不是代碼寫的太爛了,呵呵……..
遞歸的特性
1、遞歸必須要有一個結束條件,否則就是一個死循環,直到報錯
2、每次進入更深一次遞歸時,遞歸的規模會比上次遞歸有所減小
3、遞歸的執行效率不高,遞歸層次過多會導致棧溢出
遞歸的作用
用於很多計算:斐波拉契數列,漢羅塔,多級評論樹,二分查找,階乘
二分查找例子
data_set = [1,3,4,6,7,8,9,10,11,13,14,16,18,19,21] # data_set = list(range(101)) def b_search(n, low, high, d): mid = int((low + high) / 2) # 中間值 print(mid) if low == high: # 第一位 和 最後一個 對比(索引的對比) print(‘not find‘) return if d[mid] > n: print(‘go left‘, low, high, d[mid]) b_search(n, low, mid, d) if d[mid] < n: print(‘go right‘, low, high, d[mid]) b_search(n, mid, high, d) else: print(‘find it‘, d[mid]) b_search(16, 0, len(data_set), data_set)
尾遞歸
尾遞歸是對遞歸的優化,提高遞歸的效率,但是在python中並不支持,然並卵
優化:
在調用下次遞歸時,直接return自己,不保留外層函數的在內存中的數據,遞歸需要的只是這一層的信息,所以節省了內存,提高了效率
然而在python中,因為沒有優化,我們鼓勵使用叠代器來改寫尾遞歸
(引用自知乎)
python 之 遞歸