遞迴工作原理

2021-07-28 11:48:46 字數 2172 閱讀 5819

遞迴(recursion)就是子程式(或函式)直接呼叫自己或通過一系列呼叫語句間接呼叫自己,是一種描述問題和解決問題的基本方法。
遞迴通常用來解決結構自相似的問題。所謂結構自相似,是指構成原問題的子問題與原問題在結構上相似,可以用類似的方法解決。具體地,整個問題的解決,可以分為兩部分:第一部分是一些特殊情況,有直接的解法;第二部分與原問題相似,但比原問題的規模小。實際上,遞迴是把乙個不能或不好解決的大問題轉化為乙個或幾個小問題,再把這些小問題進一步分解成更小的問題,直至每個小問題都可以直接解決。因此,遞迴有兩個基本要素:
(1)邊界條件:確定遞迴到何時終止,也稱為遞迴出口。
(2)遞迴模式:大問題是如何分解為小問題的,也稱為遞迴體。遞迴函式只有具備了這兩個要素,才能在有限次計算後得出結果
在遞迴函式中,呼叫函式和被呼叫函式是同乙個函式,需要注意的是遞迴函式的呼叫層次,如果把呼叫遞迴函式的主函式稱為第0層,進入函式後,首次遞迴呼叫自身稱為第1層呼叫;從第i層遞迴呼叫自身稱為第i+1層。反之,退出第i+1層呼叫應該返回第i層。
遞迴函式的內部執行過程
乙個遞迴函式的呼叫過程類似於多個函式的巢狀的呼叫,只不過呼叫函式和被呼叫函式是同乙個函式。為了保證遞迴函式的正確執行,系統需設立乙個工作棧。具體地說,遞迴呼叫的內部執行過程如下:
(1)運動開始時,首先為遞迴呼叫建立乙個工作棧,其結構包括值參、區域性變數和返回位址;
(2)每次執行遞迴呼叫之前,把遞迴函式的值參和區域性變數的當前值以及呼叫後的返回位址壓棧;
(3)每次遞迴呼叫結束後,將棧頂元素出棧,使相應的值參和區域性變數恢復為呼叫前的值,然後轉向返回位址指定的位置繼續執行。
以階乘為例說明遞迴的工作原理:

long ff(int n)

首先要清楚,遞迴就是某個函式直接或間接地呼叫了自身,這種呼叫方式叫做遞迴呼叫。說白了,還是函式呼叫。既然是函式呼叫,那麼就有乙個雷打不動的原則:所有被呼叫的函式都將建立乙個副本,各自為呼叫者服務,而不受其他函式的影響。

你的ff函式,遞迴多少次,就有多少個副本,再利用記憶體的棧式管理,反向退出。這個最好找一下「棧」這方面的東西看看,挺容易的,就像子彈匣一樣,先進後出。

你不理解,很有可能是因為誤以為該這幾行**被反覆使用了。從某種意義上說,這是不對的,因為就像剛才說的,一旦被呼叫,他將在記憶體中複製出乙份**,再被呼叫就再複製乙份,換句話說,你可以吧同乙個函式的多次呼叫理解稱謂多個不同函式的一次呼叫,這樣也會會簡單些。

再說=1和=0是為什麼退出。遞迴,很需要注意的就是死遞迴,也就是說,某乙個函式進入了無限呼叫自身的情況,永無止境地消耗記憶體等資源,這在程式設計方面是一大忌。但凡是遞迴的函式,一定會在某乙個地方存在能夠返回上一層函式的**,否則必定死遞迴。ff函式中,那個else就是返回的出口,你可以這樣想,如果沒有那個if來進行判斷,你遞迴到什麼時候算完?ff是不是會一直呼叫自己呢?別指望被呼叫的函式會自動結束,因為一旦某個函式a中呼叫了函式b(或者自己),那麼a中的**會停在呼叫的位置,而轉向b中去執行,同理,如果b又呼叫函式c,那麼b又停在呼叫的位置,去執行c,如果無限呼叫,那麼程式是永遠不會結束的。當然,也有這種情況,a呼叫b,然後繼續自己的**,不管b的死活,這種不在我們的討論範圍內,因為那牽扯到另一種程式設計方式:多執行緒。(我們現在說的是單執行緒)

給你拆極不看看吧:

求3!=?

一層執行到f=ff(3-1)*3;停止,執行二層ff(3-1),也就是ff(2)

二層執行到f=ff(2-1)*2;停止,執行三層ff(2-1),也就是f(1)

三層執行到else if(n==0||n==1) f=1;然後return(f)到二層的ff(2-1)的位置,二層繼續執行

二層執行f=1*2; 然後就return(f)到一層ff(3-1)的位置,一層繼續執行

一層執行f=2*3; 然後就return(f)到了最初呼叫ff(3)的main函式裡,所以就得到y=6

大體過程就是這樣的

這裡每次一層都相當於乙個不同的函式,你可以給他們起名為ff1,ff2,ff3.....這樣就不混了。只要注意一點,呼叫一次,不是在**本身上執行,而是會複製出乙份在執行,雖然不太恰當,但足以說明問題。

遞迴的工作原理

理解遞迴的工作原理 為了理解遞迴的工作原理,你需要追蹤遞迴呼叫的執行過程,所以讓我們來進行這項工作。追蹤乙個遞迴函式的執行過程的關鍵是理解函式中所宣告的變數是如何儲存的。當函式被呼叫時,它的變數的空間是建立於執行時堆疊上的。以前呼叫的函式的變數扔保留在堆疊上,但他們被新函式的變數所掩蓋,因此是不能被...

WITH遞迴原理

公用表表示式 cte common table expression with target column list as union all 定位點成員只是乙個返回有效關係結果表的查詢,與用於定義非遞迴表示式的查詢類似,定位點成員查詢只被呼叫一次。下面舉例理解遞迴原理 以下 演示了如何使用遞迴ct...

js遞迴原理

本部落格主要講述關於js的函式遞迴,主要從 變數 函式 和 函式 變數 兩個方面說明解釋。相對簡單,直接上 function fun fun 用遞迴 來求 5 的階乘 n n n 1 定義乙個函式,用於求 n 的階乘 function func n func n 1 因為傳遞的引數是 n 1,那麼就...