遞歸函數
在函數內部,能夠調用其餘函數。若是一個函數在內部調用自身自己,這個函數就是遞歸函數。
舉個例子,咱們來計算階乘 n! = 1 * 2 * 3 * ... * n,用函數 fact(n)表示,能夠看出:
fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n
因此,fact(n)能夠表示爲 n * fact(n-1),只有n=1時須要特殊處理。
因而,fact(n)用遞歸的方式寫出來就是:python
def fact(n): if n==1: return 1 return n * fact(n - 1)
上面就是一個遞歸函數。能夠試試:
>>> fact(1)
1
>>> fact(5)
120
>>> fact(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L
若是咱們計算fact(5),能夠根據函數定義看到計算過程以下:
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120
遞歸函數的優勢是定義簡單,邏輯清晰。理論上,全部的遞歸函數均可以寫成循環的方式,但循環的邏輯不如遞歸清晰。
使用遞歸函數須要注意防止棧溢出。在計算機中,函數調用是經過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出。能夠試試計算 fact(10000)。數據結構
def digui(n): sum = 0 if n<=0: return 1 else: return n*digui(n-1) print(digui(5))