這幾天又翻出一本《c++大學教程·第五版》看,看著看著就看到fibonacci數列,很簡單就寫了個遞迴想算一下,**非常樸素,但是沒想到居然這麼慢,加上個gettickcount()函式一看,算到第40個數就耗費了大約31秒的時間,實在讓人汗顏,在網上搜尋了一把,發現了本文大為驚嘆,原來遞迴也是可以優化的,稍微修改了一下變為尾遞迴再計算,居然只需31毫秒,1000倍啊!
上面那個鏈結老趙寫的很好,我就不浪費口水了,給出樸素的**和優化後的**充一下字數吧。
樸素的遞迴計算fibonacci數列:
#include<
iostream
>
#include
<
ctime
>
#include
<
windows.h
>
using
std::cout;
using
std::endl;
unsigned fibonacci(
intn)
else
}int
main()
cout
<<
"it takes you
"<<
gettickcount()
-tt
<<
"ms to work it out.
"<<
endl;
return0;
}
轉變為尾遞迴之後的**:
#include<
iostream
>
#include
<
ctime
>
#include
<
windows.h
>
using
std::cout;
using
std::endl;
unsigned fibonacci(
intn,unsigned acc1,unsigned acc2)
else
}int
main()
cout
<<
"it takes you
"<<
gettickcount()
-tt
<<
"ms to work it out.
"<<
endl;
return0;
}
fibonacci(n-1,acc2,acc1+acc2)真是神來之筆,原本樸素的遞迴產生的棧的層次像二叉樹一樣,以指數級增長,但是現在棧的層次卻像是陣列,變成線性增長了,實在是奇妙,總結起來也很簡單,原本棧是先擴充套件開,然後邊收攏邊計算結果,現在卻變成在呼叫自身的同時通過引數來計算。
尾遞迴優化
尾遞迴就是遞迴語句在函式最後執行,且無需對返回值進行進一步操作。編譯器會對這種遞迴進行優化,在進入深層遞迴時候,不是在遞迴棧進行入棧操作,而是直接覆蓋棧頂。線性遞迴與尾遞迴區別如下 線性遞迴 1 2 3 4 5 longrescuvie longn 尾遞迴 1 2 3 4 5 6 7 8 9 10 ...
尾遞迴優化
什麼是尾遞迴 尾遞迴就將遞迴呼叫寫在函式的尾部return 尾遞迴的好處 解決傳統遞迴的棧溢位問題 尾遞迴適合的業務場景 1.需要遞迴優化的函式沒有用timeout等非同步佇列進行遞迴呼叫函式自己 2.需要遞迴優化的遞迴函式的返回值不是每次都返回,而是條件性返回 尾遞迴優化後的遞迴demo meth...
Kotlin尾遞迴優化
一 尾遞迴優化 1.遞迴的一種特殊形式 2.呼叫自身後無其他的操作 3.tailrec關鍵字提示編譯器尾遞迴優化 二 具體的來看看一下 說明 package net.println.kotlin.chapter5.tailrecursive author wangdong description 定...