遞迴只是讓解決方案更清晰,並沒有效能上的優勢。實際上,在有些情況下,使用迴圈的效能更好。如果使用迴圈,程式的效能可能更高;如果使用遞迴,程式可能更容易理解。
>遞迴函式的組成:
1. 基線條件(base case)即函式不再呼叫自己,從而避免無限迴圈;
2. 遞迴條件(recursive case)即自己呼叫自己。
遞迴條件一定是向基線條件靠攏的,否則,只能無限遞迴下去。
在計算結科學中是一種通過重複將問題分解為同類的子問題而解決問題的方法。
計算機科學家尼克勞斯·維爾特如此描述遞迴:遞迴的強大之處在於它允許使用者用有限的語句描述無限的物件。因此,在電腦科學中,遞迴可以被用來描述無限的運算,儘管描述運算的程式是有限的。
又稱為棧或堆疊,是一種抽象資料型別,只允許在有序的線性資料集合的一端(稱為堆疊頂端,英語:top)進行加入資料(英語:push)和移除資料(英語:pop)的運算。因而按照後進先出(lifo,last in first out)的原理運作。
堆疊常用一維陣列或者鍊錶來實現。堆疊常用兩種基本操作,推入(壓棧,push)和彈出(彈棧,pop):
1. 先入後出,**先出;
2. 除頭尾節點之外,每個元素有乙個前驅,乙個後繼。
簡單的乙個python寫法的遞迴程式示例:
def recursivetest():
recursivetest() #自己呼叫自己
以上的程式是乙個最簡單的遞迴,但因為無限呼叫自己而不會停下,就會因為**棧空間溢位**而導致程式產生異常而強制停止,而python會因為自身設定的保護措施,而不斷的丟擲異常。
簡單寫乙個不帶任何條件的遞迴函式:
def countdown(i):
print(i)
countdown(i-1)
countdown(3)
如果執行上面這個函式,我們會發現它會不停的執行。
所以編寫遞迴函式時候,你必須要告訴它什麼時候停下來(停止遞迴);加上基線條件的**就可以避免無限迴圈,示例如下:
def countdown(i):
if i <= 0: #基線條件
return
else: #遞迴條件
countdown(i-1)
countdown(3)
#3 2 1 0 程式停止
#開始執行函式greet,此時記憶體中開闢一塊空間greet 進入棧中
def greet(name):
#在greet的記憶體中,新增變數name
print("hello, " + name + "!")
#開始執行greet2,此時記憶體中開闢空間greet2,greet2入棧
#greet
greet2(name)
#greet2 執行完畢,出棧
#greet
print("getting ready to say bye...")
#開始執行bye,此時記憶體中開闢空間bye,bye入棧
#greet
bye()
#bye執行完畢,出棧
#greet
#最後greet執行完畢,出棧
可能存在無限遞迴 遞迴
一 什麼樣的問題可以用遞迴來解決?遞迴問題需要滿足的三個條件 1 問題的解可以分解為幾個子問題 資料規模更小的問題 的解 2 問題與子問題,除了資料規模不同,求解思路完全一樣 3 存在遞迴終止條件 不會無限巢狀 二 為什麼使用遞迴?遞迴的優缺點?1.優點 的表達力很強,寫起來簡潔。2.缺點 時間效率...
可能存在無限遞迴 Python之遞迴函式
我們在前面的章節中,很多次的看到了在函式中呼叫別的函式的情況,如果乙個函式在內部呼叫了自身,這個函式就被稱為遞迴函式。高斯求和 def sum number n total 0 for i in range 1,n 1 total i return total sum sum number 100 ...
第5章 遞迴
目錄 四 遞迴程式設計的應用例項 大綱未規定 五 演算法設計題 六 錯題集 資料結構與演算法 師大完整教程目錄 更有python go pytorch tensorflow 爬蟲 人工智慧教學等著你 遞迴 直接或間接的呼叫函式本身 遞迴程式的兩個特點 具備遞迴出口 在不滿足遞迴出口的情況下,把原問題...