Python函式之六 遞迴函式

2021-10-10 05:34:16 字數 4482 閱讀 1465

1、程式語言中, 函式func(type a,…)直接或間接呼叫函式本身,則該函式稱為遞迴函式。

2、遞迴的定義:一種計算過程,如果其中每一步都要用到前一步或前幾步的結果,稱為遞迴。

3、用遞迴過程定義的函式, 稱為遞迴函式。

1、呼叫方式

1.1 直接呼叫

def

func()

:print

('in func'

) func(

)func(

)

分析:這就是乙個直接呼叫自身的遞迴函式,因為沒有判斷邊界,是乙個死迴圈函式。

1.2 間接呼叫

def

foo():

print

('in foo'

) bar(

)def

bar():

print

('in bar'

) foo(

)foo(

)

分析:這是乙個間接呼叫方式的遞迴函式,foo函式和bar函式相互呼叫對方形成遞迴,也是乙個死迴圈。

1.3 總結

1、遞推:一層一層遞迴呼叫下去,進入下一層遞迴的問題規模都將會減小;

2、回溯:遞迴必須要有乙個明確的結束條件,在滿足該條件開始一層一層回溯;

3、遞迴的精髓在於通過不斷地重複逼近乙個最終的結果。

def

foo(n)

:if n ==1:

return

1else

:return n * foo(n-1)

print

(foo(5)

)#120

分析:

第一次迴圈:n = 5 返回值:5 * foo(5-1)

第二次迴圈:n = 4 返回值:5 * 4 * foo(4-1)

第三次迴圈:n = 3 返回值:5 * 4 * 3 * foo(3-1)

第四次迴圈:n = 2 返回值:5 * 4 * 3 * 2 foo(2-1)

第五次迴圈:n = 1 返回值:5 * 4 * 3 * 2 * 1 = 120

1、用迴圈的方式實現階乘

def

foo(n)

: res =

1for i in

range

(n):

res = res *

(i +1)

return res

print

(foo(5)

)#120

2、遞迴與迴圈的優缺點

2.1 遞迴

優點:**簡潔、清晰,並且容易驗證正確性。(如果你真的理解了演算法的話,否則你更暈)

缺點:1、它的執行需要較多次數的函式呼叫,如果呼叫層數比較深,每次都要建立新的變數,需要增加額外的堆疊處理,會對執行效率有一定影響,占用過多的記憶體資源。

2、遞迴演算法解題的執行效率較低。在遞迴呼叫的過程中系統為每一層的返回點、區域性變數等開闢了棧來儲存。遞迴次數過多容易造成棧溢位等。

2.2 迴圈

優點:速度快,結構簡單。

缺點:並不能解決所有的問題。有的問題適合使用遞迴而不是迴圈。如果使用迴圈並不困難的話,最好使用迴圈

1、二分法查詢

所謂二分法查詢就是在乙個區間[a, b]內查詢乙個數m,判斷m是否大於b/2,如果大於,則在[b/2,b]之間查詢,如果小於,則在[a,b/2]之間查詢,然後重複以上操作來實現的

**例項:查詢列表中[1, 3, 7, 11, 22, 34, 55, 78, 111, 115]的值:78

def

foo(n, li)

: mid_index =

int(

len(li)/2

)print

(li)

iflen

(li)==0

:print

('not find it'

)return

if n > li[mid_index]

: li = li[mid_index+1:

] foo(n, li)

elif n < li[mid_index]

: li = li[

:mid_index]

foo(n, li)

else

:print

('find it'

)li =[1

,3,7

,11,22

,34,55

,78,111

,115

]foo(

78, li)

# [1, 3, 7, 11, 22, 34, 55, 78, 111, 115]

# [55, 78, 111, 115]

# [55, 78]

# find it

2、使用遞迴列印斐波那契數列(前兩個數的和得到第三個數)
#得出斐波那契數列的第n項

deffeibo

(n):

if n <=1:

return n

else

:return feibo(n-1)

+ feibo(n-2)

defdayin

(n):

for i in

range(1

, n+1)

:print

(f'第項為:'

)dayin(10)

# 第1項為:1

# 第2項為:1

# 第3項為:2

# 第4項為:3

# 第5項為:5

# 第6項為:8

# 第7項為:13

# 第8項為:21

# 第9項為:34

# 第10項為:55

1、普通遞迴

n的階乘:

分析:第一次迴圈:n = 5 返回值:5 * foo(4)

第二次迴圈:n = 4 返回值:5 * 4 * foo(3)

第三次迴圈:n = 3 返回值:5 * 4 * 3 * foo(2)

第四次迴圈:n = 2 返回值:5 * 4 * 3 * 2 * foo(1)

第五次迴圈:n = 1 返回值:5 * 4 * 3 * 2 * 1

這種普通遞迴是通過從執行第乙個呼叫開始,都是呼叫下乙個的遞迴來計算結果,這種方式在中途無法獲取結果,只有所有遞迴都進行完畢才能得到結果。

這種方式雖然也能計算出最終的結果,但是無法操作中途的計算結果,隨著遞迴的深入,之前的一些變數需要分配堆疊來儲存。

2、尾遞迴

n的階乘:

分析:第一次迴圈:n = 5 返回值:tail_recursion(5,1)

第二次迴圈:n = 4 返回值:tail_recursion(4,5)

第三次迴圈:n = 3 返回值:tail_recursion(3,20)

第四次迴圈:n = 2 返回值:tail_recursion(2,30)

第五次迴圈:n = 1 返回值:tail_recursion(1,120) = 120

尾遞迴相對傳統遞迴,其是一種特例,實質上尾遞迴通過新增乙個引數用於接收每一次呼叫後的結果,實現了釋放上一次呼叫函式的棧記憶體。

在尾遞迴中,先執行某部分的計算,然後開始呼叫遞迴,所以可以得到當前的計算結果,而這個結果也將作為引數傳入下一次遞迴。

這也就是說函式呼叫出現在呼叫者函式的尾部,因為是尾部,所以其有乙個優越於傳統遞迴之處在於無需去儲存任何區域性變數,從記憶體消耗上,實現節約特性。

因為進入最後一步後不再需要參考外層函式(caller)的資訊,因此沒必要儲存外層函式的stack,遞迴需要用的stack只有目前這層函式的,因此避免了棧溢位風險

python函式之遞迴函式

在計算機程式設計裡,遞迴指的是乙個過程 函式不斷引用自身,直到引用的物件已知。1 自己呼叫自己 2 必須有乙個明確的結束條件 優點 缺點 計算n的階乘 def factorial n if n 1 return 1 fac n factorial n 1 return fac n 5print 的階...

Python之遞迴函式

如果乙個函式在函式內部呼叫函式本身,那麼這個函式就是遞迴函式。例如用遞迴函式計算階乘。deffact n if n 1 return 1.return n fact n 1 fact 1 1 fact 7 5040 fact 999 traceback most recent call last f...

python之函式遞迴

函式的遞迴 函式呼叫自身的程式設計技巧稱為遞迴 遞迴函式的特點 特點 特點 函式內部的 是相同的,只是針對引數不同,處理的結果不同當引數滿足乙個條件時,函式不再執行 示例 def sum numbers num print num 遞迴的出口很重要,否則會出現死迴圈 遞迴案例 計算數字累加 需求 定...