遞迴與尾遞迴

2021-06-26 08:16:36 字數 1491 閱讀 8853

1、遞迴

關於遞迴的概念,我們都不陌生。簡單的來說遞迴就是乙個函式直接或間接地呼叫自身,是為直接或間接遞迴。一般來說,遞迴需要有邊界條件、遞迴前進段和遞迴返回段。當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回。用遞迴需要注意以下兩點:

(1) 遞迴就是在過程或函式裡呼叫自身。(2) 在使用遞迴策略時,必須有乙個明確的遞迴結束條件,稱為遞迴出口。

遞迴一般用於解決三類問題:

(1)資料的定義是按遞迴定義的。(fibonacci函式,n的階乘)

(2)問題解法按遞迴實現。(回溯)

(3)資料的結構形式是按遞迴定義的。(二叉樹的遍歷,圖的搜尋)

遞迴的缺點:

遞迴解題相對常用的演算法如普通迴圈等,執行效率較低。因此,應該盡量避免使用遞迴,除非沒有更好的演算法或者某種特定情況,遞迴更為適合的時候。

在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存,因此遞迴次數過多容易造成棧溢位。

用線性遞迴實現fibonacci函式,程式如下所示:

1

int fibonaccirecursive(intn)2

遞迴寫的**非常容易懂,完全是根據函式的條件進行選擇計算機步驟。例如現在要計算n=5時的值,遞迴呼叫過程如下圖所示:

2、尾遞迴

顧名思義,尾遞迴就是從最後開始計算, 每遞迴一次就算出相應的結果, 也就是說, 函式呼叫

出現在呼叫者函式的尾部, 因為是尾部, 所以根本沒有必要去儲存任何區域性變數

. 直接讓被呼叫的函式返回時越過呼叫者, 返回到呼叫者的呼叫者去。尾遞迴就是把當前的運算結果(或路徑)放在引數裡傳給下層函式

,深層函式所面對的不是越來越簡單的問題,而是越來越複雜的問題,因為引數裡帶有前面若干步的運算路徑。

尾遞迴是極其重要的,不用尾遞迴,函式的堆疊耗用難以估量,需要儲存很多中間函式的堆疊。比如f(n, sum) = f(n-1) + value(n) + sum; 會儲存n個函式呼叫堆疊,而使用尾遞迴f(n, sum) = f(n-1, sum+value(n)); 這樣則只保留後乙個函式堆疊即可,之前的可優化刪去。

尾遞迴就是從最後開始計算, 每遞迴一次就算出相應的結果, 也就是說, 函式呼叫出現在呼叫者函式的尾部, 因為是尾部, 所以根本沒有必要去儲存任何區域性變數. 直接讓被呼叫的函式返回時越過呼叫者, 返回到呼叫者的呼叫者去.

採用尾遞迴實現fibonacci函式,程式如下所示:

1

int fibonaccitailrecursive(int n,int ret1,int

ret2)

2

例如現在要計算n=5時的值,尾遞迴呼叫過程如下圖所示:

從圖可以看出,為遞迴不需要向上返回了,但是需要引入而外的兩個空間來保持當前的結果。

遞迴與尾遞迴

1 遞迴 簡單的來說遞迴就是乙個函式直接或間接地呼叫自身,是為直接或間接遞迴。一般來說,遞迴需要有邊界條件 遞迴前進段和遞迴返回段。當邊界條件不滿足時,遞迴前進 當邊界條件滿足時,遞迴返回。用遞迴需要注意以下兩點 1 遞迴就是在過程或函式裡呼叫自身。2 在使用遞迴策略時,必須有乙個明確的遞迴結束條件...

遞迴與尾遞迴

前言 今天上網看帖子的時候,看到關於尾遞迴的應用 大腦中感覺這個詞好像在 見過,但是又想不起來具體是怎麼回事。如是乎,在網上搜了一下,頓時豁然開朗,知道尾遞迴是怎麼回事了。下面就遞迴與尾遞迴進行總結,以方便日後在工作中使用。1 遞迴 關於遞迴的概念,我們都不陌生。簡單的來說遞迴就是乙個函式直接或間接...

遞迴與尾遞迴

一 遞迴 1.定義 在電腦科學領域中,遞迴式通過遞迴函式來實現的。程式呼叫自身的程式設計技巧稱為遞迴 recursion 乙個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把乙個大型複雜的問題層層轉化為乙個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程...