遞迴呼叫效率問題,遞迴與迴圈比較

2021-07-04 08:13:14 字數 1533 閱讀 1874

1.所謂的遞迴慢到底是什麼原因呢?

大家都知道遞迴的實現是通過呼叫函式本身,函式呼叫的時候,每次呼叫時要做位址儲存,引數傳遞等,這是通過乙個遞迴工作棧實現的。具體是每次呼叫函式本身要儲存的內容包括:區域性變數、形參、呼叫函式位址、返回值。那麼,如果遞迴呼叫n次,就要分配n*區域性變數、n*形參、n*呼叫函式位址、n*返回值。這勢必是影響效率的。

2.用迴圈效率會比遞迴效率高嗎?

遞迴與迴圈是兩種不同的解決問題的典型思路。當然也並不是說迴圈效率就一定比遞迴高,遞迴和迴圈是兩碼事,遞迴帶有棧操作,迴圈則不一定,兩個概念不是乙個層次,不同場景做不同的嘗試。

2.1遞迴演算法:

優點:**簡潔、清晰,並且容易驗證正確性。(如果你真的理解了演算法的話,否則你更暈)

缺點:它的執行需要較多次數的函式呼叫,如果呼叫層數比較深,需要增加額外的堆疊處理(還有可能出現堆疊溢位的情況),比如引數傳遞需要壓棧等操作,會對執行效率有一定影響。但是,對於某些問題,如果不使用遞迴,那將是極端難看的**。

2.2迴圈演算法:

優點:速度快,結構簡單。

缺點:並不能解決所有的問題。有的問題適合使用遞迴而不是迴圈。如果使用迴圈並不困難的話,最好使用迴圈。

2.3遞迴演算法和迴圈演算法總結:

1. 一般遞迴呼叫可以處理的演算法,也通過迴圈去解決常需要額外的低效處理。

2. 現在的編譯器在優化後,對於多次呼叫的函式處理會有非常好的效率優化,效率未必低於迴圈。

3.遞迴和迴圈兩者完全可以互換。如果用到遞迴的地方可以很方便使用迴圈替換,而不影響程式的閱讀,那麼替換成遞迴往往是好的。(例如:求階乘的遞迴實現與迴圈實現。)

3.那麼遞迴使用的棧是什麼樣的乙個棧呢?

首先,看一下系統棧和使用者棧的用途。

3.1系統棧(也叫核心棧、核心棧)是記憶體中屬於作業系統空間的一塊區域,其主要用途為: (1)儲存中斷現場,對於巢狀中斷,被中斷程式的現場資訊依次壓入系統棧,中斷返回時逆序彈出; (2)儲存作業系統子程式間相互呼叫的引數、返回值、返回點以及子程式(函式)的區域性變數。

3.2使用者棧是使用者程序空間中的一塊區域,用於儲存使用者程序的子程式間相互呼叫的引數、返回值、返回點以及子程式(函式)的區域性變數。

我們編寫的遞迴程式屬於使用者程式,因此使用的是使用者棧。

4.遞迴呼叫過多導致的棧溢位

例子:劍指offer中題目五 從尾到頭列印鍊錶 用遞迴實現

當鍊表很長時,遞迴層級過深,可能導致棧溢位

那麼過多的遞迴呼叫為什麼會引起棧溢位呢?事實上,函式呼叫的引數是通過棧空間來傳遞的,在呼叫過程中會占用執行緒的棧資源。而遞迴呼叫,只有走到最後的結束點後函式才能依次退出,而未到達最後的結束點之前,占用的棧空間一直沒有釋放,如果遞迴呼叫次數過多,就可能導致占用的棧資源超過執行緒的最大值,從而導致棧溢位,導致程式的異常退出。

遞迴的效率問題及遞迴與迴圈比較

遞迴的效率問題及遞迴與迴圈比較 1.所謂的遞迴慢到底是什麼原因呢?大家都知道遞迴的實現是通過呼叫函式本身,函式呼叫的時候,每次呼叫時要做位址儲存,引數傳遞等,這是通過乙個遞迴工作棧實現的。具體是每次呼叫函式本身要儲存的內容包括 區域性變數 形參 呼叫函式位址 返回值。那麼,如果遞迴呼叫n次,就要分配...

java遞迴的效率問題及遞迴與迴圈比較

1.所謂的遞迴慢到底是什麼原因呢?大家都知道遞迴的實現是通過呼叫函式本身,函式呼叫的時候,每次呼叫時 要做位址儲存,引數傳遞等,這是通過乙個遞迴工作棧實現的。具體是每次 那麼,如果遞迴呼叫n次,就要分配n 區域性變數 n 形參 n 呼叫函式位址 n 返回值。這勢必是影響效率的。2.用迴圈效率會比遞迴...

JAVASCRIPT 遞迴與迴圈的效率比較

優點 簡潔 清晰,並且容易驗證正確性。如果你真的理解了演算法的話,否則你更暈 缺點 它的執行需要較多次數的函式呼叫,如果呼叫層數比較深,需要增加額外的堆疊處理,比如引數傳遞需要壓棧等操作,會對執行效率有一定影響。但是,對於某些問題,如果不使用遞迴,那將是極端難看的 優點 速度快,結構簡單。缺點 並不...