資料結構與演算法 10 遞迴

2021-09-25 08:25:12 字數 2338 閱讀 9087

深入理解遞迴

舉個假想的例子:咱來到cba上海隊球館看一場激烈的常規賽,賽場座位都坐滿了,這時候女朋友/老婆大人問你我們現在坐的是第幾排?人這麼多,個子矮,看不清咋辦?遞迴派上用場了:問前面的朋友他是第幾排?在他的排數上 +1 就知道自己的排數了。那前面的朋友一臉萌比也不知道怎麼辦呢?沒事,告訴他讓他也按照你這個辦法問下去。這樣一直下去,到了第一排的朋友他們肯定知道自己是第一排,然後依次返回,最後我們就知道我們是第幾排了。哈哈,是不是很有趣?(嚴重宣告:小心被人當作傻子~哈哈)。

在這個場景中,依次問過去的這個展開過程叫「」;後面依次返回答案的這個過程叫「」。

遞推公式表示:

f(n) = f(n-1) +1

f(1) = 1

其中,f(n) 表示我的排數,f(n-1) 表示前面一位的排數,f(1)表示第一排的排數。

遞推公式轉換為遞迴**:

def

f(n)

:if n ==1:

return

1return f(n-1)

+1

最後,貼乙個維基百科對遞迴的解釋:遞迴(英語:recursion),又譯為遞迴,在數學與電腦科學中,是指在函式的定義中使用函式自身的方法。可以理解為自我複製的過程。

遞迴應用非常廣泛,是後續很多複雜資料結構和演算法的基礎,而且平時程式設計設計中也常常會運用到遞迴的思想,所以一定要拿下他!

例子:爬樓梯問題。一次可以跨 1 階或 2 階樓梯,總共有 10 階樓梯,請問走完這 10 階樓梯總共有多少種可能的走法?

思考,

遞推公式為:

f(n) = f(n-1) + f(n-2)

f(2) = 2

f(1) = 1

**:

def

f(n)

:if n ==1:

return

1if n ==2:

return

2return f(n-1)

+ f(n-

2)

人腦屬於線性思維,分析線性的問題還比較擅長,人腦不太適合同一時刻分析多條線,在遞迴中也是如此。

上面球館作為的問題屬於「原始問題分解為乙個子問題」,這是比較容易理解的;有時還會遇到「原始問題分解為多個子問題」的情況,比如前面的爬樓梯問題。這種情況就不好像分解為乙個子問題那樣在腦海中一步一步一層一層將每個字問題都捋清楚了,如果想這樣把遞迴的每一步都搞清楚就陷入了思維誤區。

分析遞迴的正確思路:只需要將 a 問題分解為 b,c 問題,並假設b和c問題已經解決,在此基礎上分析 a 和 b, c的關係即可,不要試圖在腦海中去分解遞迴的每個步驟。

由前面棧的知識,我們都知道,函式呼叫的時候會將上乙個函式作為棧幀入棧。遞迴本質上就是深層次的函式呼叫,那麼會存在乙個問題,就是當遞迴的深度很深時,入棧的函式棧幀就會增多,而每個執行緒的棧記憶體空間是有限的,極端情況下如果遞迴深度無限深,那麼肯定會出現棧溢位,這可是會引起系統宕機等嚴重問題的。

遞迴棧溢位的解決辦法

def

f(n)

:if n ==1:

return

1if n ==2:

return2

pre =

2 ppre =

1for i in

range(3

, n+1)

: cur = pre + ppre

ppre = pre

pre = cur

return cur

if __name__ ==

"__main__"

:print

(f(5

))

還是拿前面的爬樓梯問題來看。

f(5) = f(4) + f(3)

f(4) = f(3) + f(2)

==> f(5) = (f(3) + f(2)) + f(3)

這裡發現會出現重複計算 f(3)的情況,資料量增大時重複計算的情況也會大大增多,這就造成了資源的浪費和效率的降低。為了解決這個問題,可以將已經計算過的情況先儲存起來(比如 hashtable),後面判斷遇到計算過的值時直接拿出來用即可。

從時間複雜度來看,遞迴呼叫越深,耗費的時間會越多;

從空間複雜度來看,遞迴每次呼叫函式都會棧幀入棧,意味著執行記憶體的增加,空間複雜度達到o(n)(注意不是o(1))。

本質上來說,解決辦法都是合理設定遞迴深度或者改為非遞迴實現。

資料結構與演算法 10 遞迴呼叫

遞迴詳解 典型遞迴介紹 1.如何理解 遞迴 什麼是遞迴 去的過程叫 遞 回來的過程叫 歸 f n f n 1 1 備註 去的過程入棧的過程,回來的過程出棧 2.遞迴需要滿足的三個條件 遞迴的特點 2.1.乙個問題的解可以分解為幾個子問題的解 2.2.這個問題與分解之後的子問題,除了資料規模不同,求解...

資料結構與演算法 遞迴

一 概念 遞迴是一種高效 簡介的編碼技巧,一種應用很廣泛的演算法,比如dfs深度優先搜尋,前中後序二叉樹遍歷等都是使用遞迴。方法或函式呼叫自身的方式成為遞迴呼叫,呼叫稱為遞,返回成為歸 所有遞迴問題都可以用遞迴公式來表示 二 遞迴優缺點 優點 簡潔 缺點 堆疊溢位風險 可根據調整遞迴呼叫的最大深度來...

資料結構與演算法 認識遞迴

淺識 1 遞迴與迴圈 理論上,任何迴圈都可以重寫為遞迴形式 有些語言沒有迴圈語句,只能使用遞迴。2 迴圈改遞迴 1 發現邏輯 相似性 2 一定要有 出口 不然就會死迴圈 3 構造相似性 如果沒有明顯的相似性,可能是缺少引數,需要主動構造,與遞推類似 4 遞迴呼叫 1 遞迴呼叫僅僅是被調函式正好是主調...