Python遞迴演算法詳解
遞迴的概念很簡單,如果函式包含了對其自身的呼叫,該函式就是遞迴的。
遞迴(Recursion),在數學與電腦科學中,是指在函式的定義中使用函式自身的方法。
在使用遞迴時,需要注意以下幾點:
遞迴就是在過程或函式裡呼叫自身
必須有一個明確的遞迴結束條件,稱為遞迴出口。
注意: 切勿忘記遞迴出口,避免函式無限呼叫。
遞迴基本步驟
每一個遞迴程式都遵循相同的基本步驟:
1.初始化演演算法。遞迴程式通常需要一個開始時使用的種子值(seed value)。要完成此任務,可以向函式傳遞引數,或者提供一個入口函式,這個函式是非遞迴的,但可以為遞迴計算設定種子值。
2.檢查要處理的當前值是否已經與基線條件相匹配(base case)。如果匹配,則進行處理並返回值。
3.使用更小的或更簡單的子問題(或多個子問題)來重新定義答案。
4.對子問題執行演演算法。
5.將結果合併入答案的表示式。
6.返回結果。
基線條件(base case)。基線條件是遞迴程式的層位置,在此位置時沒有必要再進行操作,可以直接返回一個結果。所有遞迴程式都必須至少擁有一個基線條件,而且必須確保它們最終會達到某個基線條件;否則,程式將永遠執行下去,直到程式缺少記憶體或者棧空間。
主要應用範圍
遞迴演演算法一般用於解決三類問題:
(1)資料的定義是按遞迴定義的。(比如Fibonacci函式)
(2)問題解法按遞迴演演算法實現。(回溯)
(3)資料的結構形式是按遞迴定義的。(比如樹的遍歷,圖的搜尋)
典型的演演算法
大多數學過數學、電腦科學或者讀過程式設計相關書籍的人,想必都會遇到階乘:
n! = 1 × 2 × 3 × … × n
也可以用遞迴方式定義:
n! = (n-1)! × n
其中,n >= 1,並且 0! = 1。
由於簡單、清晰,因此其常被用作遞迴的示例。
PS: 除了階乘以外,還有很多演演算法可以使用遞迴來處理,例如:斐波那契數列、漢諾塔等。
非遞迴實現
1
2
3
4
5 |
def
factorial(n):
result
=
1
for
i
in
range
(
2
, n
+
1
):
result
*
=
i
return
result |
階乘函式的遞迴實現
1
2
3 |
def
factorial(n):
if
n
=
=
0
or
n
=
=
1
:
return
1
else
:
return
(n
*
factorial(n
-
1
)) |
遞迴過程
為了明確遞迴步驟,對 5! 進行過程分解:
1
2
3
4
5
6
7
8
9
10 |
factorial(
5
)
# 第 1 次呼叫使用 5 5
*
factorial(
4
)
# 第 2 次呼叫使用 4 5
*
(
4
*
factorial(
3
))
# 第 3 次呼叫使用 3 5
*
(
4
*
(
3
*
factorial(
2
)))
# 第 4 次呼叫使用 2 5
*
(
4
*
(
3
*
(
2
*
factorial(
1
))))
# 第 5 次呼叫使用 1 5
*
(
4
*
(
3
*
(
2
*
1
)))
# 從第 5 次呼叫返回 5
*
(
4
*
(
3
*
2
))
# 從第 4 次呼叫返回 5
*
(
4
*
6
)
# 從第 3次呼叫返回 5
*
24
# 從第 2 次呼叫返回 120
# 從第 1 次呼叫返回 |
還是這個函式factorial(N),讓我們試試N = 999和N = 1000,問題來了,N = 999時能輸出正確答案,但當N = 1000時,就出現下面的錯誤了:
RuntimeError: maximum recursion depth exceeded
於是,請記住,預設的Python有一個可用的遞迴深度的限制,以避免耗盡計算機中的記憶體。預設是1000。
遞迴優缺點
優點:
遞迴使程式碼看起來更加整潔、優雅
可以用遞迴將複雜任務分解成更簡單的子問題
使用遞迴比使用一些巢狀迭代更容易
缺點:
遞迴的邏輯很難除錯、跟進
遞迴演演算法解題的執行效率較低。在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存。遞迴次數過多容易造成棧溢位等。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952502/viewspace-2942932/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python進階-演算法-遞迴Python演算法遞迴
- 遞迴演算法遞迴演算法
- 演算法小專欄:遞迴與尾遞迴演算法遞迴
- 【演算法】遞迴演算法演算法遞迴
- Java遞迴演算法Java遞迴演算法
- 遞迴演算法要素遞迴演算法
- 漢諾塔的圖解遞迴演算法圖解遞迴演算法
- 快速排序(遞迴及非遞迴演算法原始碼)排序遞迴演算法原始碼
- 演算法初探--遞迴演算法演算法遞迴
- 揹包問題的遞迴與非遞迴演算法遞迴演算法
- 解讀:什麼是Java的遞迴演算法?Java遞迴演算法
- Python遞迴函式,二分查詢演算法Python遞迴函式演算法
- JavaScript演算法之遞迴JavaScript演算法遞迴
- 淺談遞迴演算法遞迴演算法
- 每日一演算法:遞迴演算法遞迴
- python3:遞迴解漢諾塔問題Python遞迴
- 【大爽python演算法】遞迴演算法進化之回溯演算法(backtracking)Python演算法遞迴
- 1.5.6 python遞迴函式Python遞迴函式
- 13.0、python遞迴函式Python遞迴函式
- 遞迴 & 分治演算法深度理解遞迴演算法
- Java遞迴演算法的使用Java遞迴演算法
- 演算法分析__遞迴跟蹤演算法遞迴
- python-動態規劃的遞迴、非遞迴實現Python動態規劃遞迴
- ?30 秒瞭解尾遞迴和尾遞迴優化遞迴優化
- 【演算法圖解】讀書筆記:第3章 遞迴演算法圖解筆記遞迴
- 瞭解 JavaScript 的遞迴JavaScript遞迴
- python遺傳演算法(詳解)Python演算法
- 遞迴和尾遞迴遞迴
- 【電腦科學】演算法——遞迴演算法遞迴
- 遞迴與分治演算法練習遞迴演算法
- 二十一、氣泡排序演算法——JAVA實現(遞迴與非遞迴)排序演算法Java遞迴
- 二叉樹——後序遍歷的遞迴與非遞迴演算法二叉樹遞迴演算法
- 快速排序【遞迴】【非遞迴】排序遞迴
- 微課|中學生可以這樣學Python(8.4節):遞迴演算法例題講解1Python遞迴演算法
- 微課|中學生可以這樣學Python(8.4節):遞迴演算法例題講解3Python遞迴演算法
- 微課|中學生可以這樣學Python(8.4節):遞迴演算法例題講解2Python遞迴演算法
- Python 八皇后解法(非遞迴版本)Python遞迴
- js遞迴遍歷講解JS遞迴