python 遞歸與遞歸函數
遞歸的定義——在一個函數裏再調用這個函數本身
現在我們已經大概知道剛剛講的story函數做了什麽,就是在一個函數裏再調用這個函數本身,這種魔性的使用函數的方式就叫做遞歸。
剛剛我們就已經寫了一個最簡單的遞歸函數。
遞歸的最大深度——997
正如你們剛剛看到的,遞歸函數如果不受到外力的阻止會一直執行下去。但是我們之前已經說過關於函數調用的問題,每一次函數調用都會產生一個屬於它自己的名稱空間,如果一直調用下去,就會造成名稱空間占用太多內存的問題,於是python為了杜絕此類現象,強制的將遞歸層數控制在了997
可以用一段代碼來驗證默認遞歸深度:
1 def foo(n): 2 print(n) 3 n += 1 4 foo(n) 5 foo(1)
可以通過一定方法來修改默認遞歸深度:
1 import sys 2 print(sys.setrecursionlimit(100000))
遞歸實力實例講解:
現在你們問我,alex老師多大了?我說我不告訴你,但alex比 egon 大兩歲。
你想知道alex多大,你是不是還得去問egon?egon說,我也不告訴你,但我比武sir大兩歲。
你又問武sir,武sir也不告訴你,他說他比金鑫大兩歲。
那你問金鑫,金鑫告訴你,他40了。。。
這個時候你是不是就知道了?alex多大?
1 金鑫 40
2 武sir 42
3 egon 44
4 alex 46
以上的過程已經非常接近遞歸的思想,再具體的分析一下這幾個人之間的規律。
使用代碼表示就是:
1 age(4) = age(3) + 2 2 age(3) = age(2) + 2 3 age(2) = age(1) + 2 4 age(1) = 40
相應的,函數應該這樣寫:
1 def age(n): 2 if n == 1: 3 return 40 4 else: 5 return age(n-1)+2 6 7 print(age(4))
由此可以得到遞歸和遞歸函數的本質:通過兩級之間的關系不斷往已知條件查找(未知聯系已知)使用已知條件來解決未解的問題。
遞歸的實際應用:算法(二分法查找)
對一串簡單的,按照大小排序的數,要找到其中一個數的位置,應該怎麽做?
按照常規的方法,使用index(要查找對象)就可以解決。
但是對於一個有幾百萬個有序排列的數的列表,使用起來就會非常慢以至於不能計算出結果。
所以我們要找一個方法來解決這樣一個問題------二分法(基於遞歸函數)
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]
我們每次都取中間的數,根據中間的數的大小來決定我們要找的數的位置(左邊or右邊)
這樣每次不斷取,就可以不斷接近要取的數的位置了,最後就可以找到我們要找的數的位置了。
這就是二分查找算法!
那麽落實到代碼上我們應該怎麽實現呢?
簡單版本:
1 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] 2 3 def func(l,aim): 4 mid = (len(l)-1)//2 5 if l: 6 if aim > l[mid]: 7 func(l[mid+1:],aim) 8 elif aim < l[mid]: 9 func(l[:mid],aim) 10 elif aim == l[mid]: 11 print("bingo",mid) 12 else: 13 print(‘找不到‘) 14 func(l,66) 15 func(l,6)
高端版本:
1 def search(num,l,start=None,end=None): 2 start = start if start else 0 3 end = end if end else len(l) - 1 4 mid = (end - start)//2 + start 5 if start > end: 6 return None 7 elif l[mid] > num : 8 return search(num,l,start,mid-1) 9 elif l[mid] < num: 10 return search(num,l,mid+1,end) 11 elif l[mid] == num: 12 return mid
---恢復內容結束---
遞歸的定義——在一個函數裏再調用這個函數本身
現在我們已經大概知道剛剛講的story函數做了什麽,就是在一個函數裏再調用這個函數本身,這種魔性的使用函數的方式就叫做遞歸。
剛剛我們就已經寫了一個最簡單的遞歸函數。
遞歸的最大深度——997
正如你們剛剛看到的,遞歸函數如果不受到外力的阻止會一直執行下去。但是我們之前已經說過關於函數調用的問題,每一次函數調用都會產生一個屬於它自己的名稱空間,如果一直調用下去,就會造成名稱空間占用太多內存的問題,於是python為了杜絕此類現象,強制的將遞歸層數控制在了997
可以用一段代碼來驗證默認遞歸深度:
1 def foo(n): 2 print(n) 3 n += 1 4 foo(n) 5 foo(1)
可以通過一定方法來修改默認遞歸深度:
1 import sys 2 print(sys.setrecursionlimit(100000))
遞歸實力實例講解:
現在你們問我,alex老師多大了?我說我不告訴你,但alex比 egon 大兩歲。
你想知道alex多大,你是不是還得去問egon?egon說,我也不告訴你,但我比武sir大兩歲。
你又問武sir,武sir也不告訴你,他說他比金鑫大兩歲。
那你問金鑫,金鑫告訴你,他40了。。。
這個時候你是不是就知道了?alex多大?
1 金鑫
2
3
4
python 遞歸與遞歸函數