程式設計思考 1 遞迴和迭代再思考

2021-06-20 05:51:52 字數 2349 閱讀 6202

首先上兩個例子

//菲波那切定理的迭代和遞迴實現

//遞迴實現:

int fib1(int n)

//迭代實現

int fib2(int n)

return f1;

}//最大公約數的迭代和遞迴

//遞迴問題

int max_common_digui(int x, int y)

else

}//迭代解決

int max_common_diedai(x,y)

}}

林銳博士的高質量c++對遞迴進行了很精闢的講解,下面是我自己對他講解的一種歸納和理解。

遞迴是乙個逐步分解的過程,通過函式呼叫自己,將問題逐步分解為多個自己去計算(逐個壓棧),然後所有結果達到基本條件後再返回值,並銷毀的過程(逐個出棧)這裡面有兩個思想:乙個是逐步分解,將複雜問題(這個複雜主要體現在規模上)化為單個問題去解決。另乙個是入棧出棧的問題,這個是記憶體分配和儲存的問題。

遞迴有兩個條件

1 能夠遞迴,也就是能夠通過不斷呼叫自己完成任務的分解,我覺得其實就是可分解性。

2 遞迴停止的條件。就是遞迴不斷分解後直到能夠解決的那個簡單問題,在這個時候就能夠獲取真正有價值的資料結果了。然後用這個結果一層層再返回過去,使得初始的問題得到解決。

遞迴實現的機理保證

(1)記憶體上的保證函式的堆疊可以根據函式執行的需求自動增長,直到能夠提供的最大記憶體都耗乾了。(如果不能動態增加,那麼自己不斷呼叫自己,**來那麼多堆疊分配儲存空間)

(2) 結構上的保證遞迴從邏輯上就是壓棧和出棧。 但凡遞迴沒有滿足基本條件,我就不斷的遞迴下去,不斷開闢儲存空間,呼叫新的遞迴函式,出棧出棧下去,每一層的遞迴函式都等著下一層遞迴的函式返回值過來,他們就一直等啊等,不會被銷毀。而一旦達到基本條件,整個程式就會從最末端的遞迴子程式逐步返回值,同時自己也進行銷毀,也就是出棧了。這樣從下往上,各個遞迴函式就會一層一層的接到下面遞迴子函式傳來的值,傳給自己的上級,同時自己也銷毀了,直到最上面一層的遞迴函式得到了返回值,貢獻給主函式,同時自己也銷毀了壓棧(進棧)是個從上往下繁衍創生的過程,出棧是個自下而上完成任務然後自我銷毀的過程。(突然覺得這個場景很悲壯。。。) 

3遞迴和迭代的不同

(1)首先二者轉換的關係:任何用遞迴實現的問題,都可以用迭代來實現。

其次遞迴的優勢和劣勢:

遞迴反覆呼叫函式,生成大量堆疊空間,執行開銷大。但是遞迴能夠直觀反應問題,可讀性強。        

迭代的優勢和劣勢只發生在乙個函式內部,反覆使用區域性變數計算,開銷小得多。再次,個人認為,遞迴是函式層面的重複呼叫,迭代是定義了乙個全域性的游標,在變數層面進行重複賦值。遞迴的具體實現是通過a函式中包含a函式 a不斷衍生和返回。而迭代的實現則是靠while迴圈和i=i%2這類的自我有條件的反覆賦值進行的。

4 從格式和通訊傳遞上思考

遞迴1 分解就是分解,除了對入口函式引數需要修改更新之外,其他不需要什麼操縱了

2 真正有資料值返回的地方就是判斷停止遞迴的地方,這個地方真正返回實際的資料,然後整個棧開始往**,把資料都收回來。

最經典的遞迴函式套路是這樣的

def 遞迴(入口引數1,入口引數2)

if(判斷條件1):

求值return 求值結果

else:

問題分解,分解出子問題

遞迴(入口引數1更新,新入口引數更新);

return 遞迴集

遞迴函式的過程一定有個通訊過程,

當遞迴的時候,從外向內訊息的傳遞時通過入口引數渠道完成的,

而當遞迴到中止條件,我們求值的時候,又通過return這個渠道從內向外將值傳回去。

迭代 迭代不管是while還是for迴圈,乙個全域性的游標在外面,保證迭代可以不斷重複賦值,到滿足條件的時候通過return把他們迭代完的值返回來。

迭代常用的格式可以是這樣的

定義外部游標變數cursor

for( 事先確定的迭代次數):

1-利用cursor進行賦值,計算。

2-對cursor進行更新,直到迭代次數為止。

while( 事先確定的迭代次數):

1-利用cursor進行賦值,計算。

2-對cursor進行更新,直到迭代次數為止。

5 從記憶體上思考

迭代的游標使用的記憶體都是那一塊,只不過隨著迭代,值被多次更新而已,但是記憶體消耗是平穩的。

而遞迴儘管我們看到遞迴過程的**都是那幾個,但是每次遞迴都是乙個新的生產的過程,這就像乙個巢狀的過程,每個新的遞迴函式都意味著產生乙個新的計算和儲存資源,儘管遞迴名字相同,但是所用的記憶體塊是絕對不一樣的,遞迴之間唯一的傳遞取代就是入口引數而已,他們沒有任何共用變數的地方存在

6 遞迴都是呼叫自己,不要使用間接遞迴,即乙個函式通過呼叫另乙個函式來呼叫自己,損害清晰性。 

專案迭代流程和思考

近期在某中小型網際網路公司經歷,迭代流程進行總結。1.首先迭代流程圖如下 希望大家能給一些優化建議,互相學習 2.迭代過程中的思考 需求階段 1 明確真實專案背景和預期。pm識別偽需求,明確需求方真正的目標和背景預期。文件及時更新和周知。ui變更及時通知。2 需求變更等落實prd做到周知。需求變更,...

演算法複習1 關於遞迴的思考

昨天在牛客上做了幾個遞迴的題目,分別是斐波那契數列,跳台階,跳台階,矩形覆蓋,這幾個題實際上是同乙個題。以下是題目 1.斐波那契數列 大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項 從0開始,第0項為0 n 39 2.跳台階 乙隻青蛙一次可以跳上1級台階,也可以跳上2級...

design pattern的學習和思考(1)

最近寫tlibrary,有了很多軟體架構方面的思考,也覺得自己在這方面理論知識的不足,從網上down了一本電子書,就叫design pattern,它介紹了很多相關的設計模式,覺得收穫很大,不過,這本書有個缺點,就是敘述過於枯燥,實在不適合閱讀,應該是說是一本不錯的reference book,我想...