????????函數調用自己的編程方式被稱為函數的遞歸調用。遞歸通常能夠將一個大型的復雜問題的遞歸條件,一層一層的回溯到終止條件,然后再根據終止條件的運算結果,一層一層的遞進運算到滿足全部的遞歸條件。它能夠使用少量程序描述出解題過程中的重復運算部分,減少程序的代碼量。要使用遞歸的方式進行編程,需要在編程的時候規劃好終止條件,寫好遞歸條件,用回溯的邏輯方法解決問題。
下面我們來舉個例子:
1.使用遞歸函數,求斐波那契數列的前10個數
def fib(n):if n==1 or n==0:return 1else:return fib(n-2)+fib(n-1)for n in range(10):print(fib(n),end='\t')
說明:斐波那契數列是一個常用的數學數列,第n個斐波那契數fib(n)由以下兩個條件決定:
(1) n = 0或n = 1時:
? fib(0) = 1,fib(1) = 1
?(2) n > 1時:
??fib(n) = fib(n-1) + fib(n-2)
【代碼分析】
(1) 第1行,在定義一個名為fib的函數,傳遞給這個函數的參數為n。
(2) 由題設,斐波那契數列中,n == 0或n == 1時,fib(0) 與fib(1) 都等于 1,我們把這個叫做終止條件。
(3) 第2、3行,在程序中實現終止條件。終止條件,一般都會給定一個或多個數值,或實現某些特定操作。
(4) 由題設,斐波那契數列中,從第三個數開始,第n個斐波那契數的數值,是由公式fib(n) = fib(n-1) + fib(n-2)計算得到,我們稱這個是遞歸條件。
(5) 第5行,在程序中實現了遞歸條件。
(6) 第7、8行,使用循環,傳遞0到9,共10個數字進fib函數。
(7) 當n == 0 和n == 1時,fib的返回值都為1。
(8) 當n == 2時,第3行不會運行,會運行第5行。第5行中,會調用fib(0)和fib(1),會執行:fib(2) = fib(0) + fib(1)。
(9) 當n == 3時,第2行、第3行不會運行,會運行第5行。第5行中,會調用fib(1)和fib(2),會執行:fib(3) = fib(1) + fib(2)。但是fib(2)此時會重復(7)中所描述的動作,所以此時fib(3) = fib(1) + fib(2) = fib(1) + (fib(0) + fib(1))。
(10) 當n == 4時,第2行、第3行不會運行,會運行第5行。第5行中,會調用fib(2)和fib(3),會執行:fib(4) = fib(2) + fib(3)。但是fib(2)此時會重復(7)中所描述的動作,fib(3)會重復(8)中所描述過程,所以此時fib(4) = fib(2) + fib(3) = (fib(0) + fib(1)) + (fib(1) + fib(2)) =? (fib(0) + fib(1)) + (fib(1) + (fib(0) + fib(1)))。
????????每次n無法滿足終止條件時,fib(n)都會回溯到fib(n-1)和fib(n-2),只有當n滿足了終止條件(n == 0和n == 1)時,fib(n)才會返回一個確定值,然后根據這個確定的值開始計算。簡單的說,遞歸函數,會執行上述過程……、(10)、(9)、(8),直到(7)。
注意:
????????當遞歸層數超過了系統允許的最大遞歸深度。默認情況下,當遞歸調用到1000層,Python解釋器將終止程序。遞歸深度是為了防止無限遞歸錯誤而設計的,當用戶編寫的正確遞歸程序需要超過1000層時,可以通過如下代碼設定:
??? import syssys.setrecursionlimit(2000)? #2000是新的遞歸層數