遞迴優化 尾遞迴果然給力

2022-02-10 23:40:49 字數 1433 閱讀 9147

這幾天又翻出一本《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 定...