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 遞迴的出口很重要,否則會出現死迴圈 遞迴案例 計算數字累加 需求 定...