謹慎使用C的遞迴

2021-10-11 16:30:20 字數 1332 閱讀 5752

斐波那契數列(fibonacci)的定義如下:

抽象為函式:

這種遞迴形式的定義容易誤導人使用遞迴來實現,但是真的該使用遞迴嗎?

每個遞迴呼叫都會觸發另外2個遞迴呼叫,而這2個呼叫的任何乙個又將觸發2個遞迴呼叫,再接下去的呼叫也是如此。這樣,冗餘計算的數量增長的非常快。

當n=30時,等了一會,終於列印完了,時間主要花在列印上,但是也足以說明這個呼叫次數之多,總共呼叫了832039次,其中n為3的呼叫317811次。

例如:在遞迴計算fibonacci(10)時,fibonacci(3)的值被計算了21次。但是在遞迴計算fibonacci(30)時,fibonacci(3)的值被計算了317811次。當然,這317811次計算所產生的結果是完全一樣的,除了其中之一外,其餘都是純屬浪費。這個額外的開銷相當恐怖。

我們知道遞迴的原理是函式呼叫的堆疊儲存本次呼叫的資料,下一次的呼叫時之前的呼叫資料被隱藏,隨著函式的返回,原來的變數被恢復。一旦遞迴次數過多,將會帶來巨大的堆疊消耗,而且效率也極低。

long fibonacci(int n) 

debug_count++;

if (n == 3)

return fibonacci(n-1) + fibonacci(n-2);

}int main ()

輸出: fibonacci : 832040

既然這個效率如此低下,我們肯定是萬不得已不使用它,除非演算法極其複雜,而使用遞迴卻能很好的實現,這樣子就可以拿巨大的效率來換,萬不得已不使用!!!

上面的這樣乙個簡單的fibonacci不適用遞迴如何實現呢?

long fibonacci(long n) 

return f3;

}int main ()

輸出: fibonacci : 832040

這個效率比前面的遞迴高太多了。所以不要在非必要的時候使用遞迴實現。

union的謹慎使用

include using namespace std float float666 myfloat 666 myinteger myinteger 1 return myfloat int main float float666 float666 coutmyinteger也被賦值了,myinte...

謹慎使用viewWithTag

uilabel cl title self viewwithtag 101 cl title.text infos total time uilabel cl distance self viewwithtag 102 cl distance.text infos distance uilabel ...

對於drawRect使用,謹慎使用

1.drawrect簡介 drawrect方法在uiview的使用上起著十分關鍵的作用。不知道大家注意過沒有,每一次建立uiview子類檔案時候,會有自動帶有已注釋的drawrect方法,也許從這一點就能看出這個方法的重要性。該方法定義在uiview uiviewrendering 分類裡面,望文生...