更新時(shí)間:2020-04-24 14:15:18 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽4892次
遞歸是工作中經(jīng)常會(huì)使用到的一種算法,比如階乘的計(jì)算就是利用遞歸來(lái)實(shí)現(xiàn)的,如果您還沒(méi)有接觸編程方面的內(nèi)容,要理解遞歸其實(shí)并不困難,它就是在一個(gè)函數(shù)的內(nèi)部調(diào)用了本身,執(zhí)行的情況特別類似是一個(gè)循環(huán),如果要這么說(shuō)遞歸似乎沒(méi)有什么好說(shuō)的,但是在這里我希望和大家討論的是遞歸這種算法在使用的時(shí)候?qū)ο到y(tǒng)性能的影響,同時(shí)也會(huì)和大家分析下在遞歸函數(shù)執(zhí)行過(guò)程中內(nèi)存的變化情況。
特別提醒,在下述內(nèi)容中方法和函數(shù)是同一個(gè)意思。
遞歸的實(shí)現(xiàn)
為了讓大家更好的理解接下來(lái)介紹的內(nèi)容,同時(shí)也為了照顧那些并沒(méi)有了解過(guò)遞歸的讀者,這里我們先來(lái)為搭建演示下在Java中到底如何通過(guò)遞歸來(lái)實(shí)現(xiàn)階乘計(jì)算的:

對(duì)于上述這段代碼來(lái)說(shuō),開(kāi)發(fā)人員并不陌生,這也是階乘最簡(jiǎn)單的例子,大家可以看到在階乘運(yùn)算函數(shù)factorial()中,如果傳入的參數(shù)大于1的話,就會(huì)進(jìn)行一次乘法運(yùn)算,通過(guò)斷點(diǎn)調(diào)試?yán)斫膺@個(gè)過(guò)程并不困難,但是在這里想和大家討論的是在這個(gè)階乘運(yùn)算過(guò)程中,系統(tǒng)的內(nèi)存是如何變化的呢?在上一篇文章中和大家提到過(guò),在系統(tǒng)運(yùn)行過(guò)程中函數(shù)參數(shù)以及其中的變量都會(huì)存放在棧中,那么像這種重復(fù)調(diào)用自己的函數(shù)它的棧是如何變化的呢?通過(guò)研究這種變化,就可以知道這種算法在工作中對(duì)系統(tǒng)的性能有多大的影響,這是一個(gè)值得所有開(kāi)發(fā)人員思考的問(wèn)題。
遞歸的分析
要研究清楚剛才的問(wèn)題,我們必須先清楚在程序運(yùn)行過(guò)程中,如果一個(gè)函數(shù)調(diào)用了另外一個(gè)函數(shù),那么接下來(lái)會(huì)發(fā)生怎樣的情況?這里設(shè)置了這樣一段代碼,就是當(dāng)數(shù)值小于10的時(shí)候,加上1輸出,如果大于10的話,需要先減去10,再加上1輸出(當(dāng)然,這段代碼沒(méi)有任何作用,純粹是為了制造一個(gè)這樣的場(chǎng)景),在Java中可以用如下的方法實(shí)現(xiàn):

我們可以看到,在這段代碼中,add中調(diào)用了另外一個(gè)方法sub,但是這時(shí)候add方法并沒(méi)有結(jié)束,所以在程序中應(yīng)該存在兩個(gè)棧,分別是存儲(chǔ)sub、add兩個(gè)方法中內(nèi)容的,也就是如下情況:

為什么sub對(duì)應(yīng)的棧會(huì)在add上邊呢?這是因?yàn)闂J呛筮M(jìn)先出的,因?yàn)閟ub方法在add方法之后執(zhí)行,所以sub對(duì)應(yīng)的棧應(yīng)該在add上邊,當(dāng)sub方法執(zhí)行完畢之后,系統(tǒng)自動(dòng)銷毀這塊空間,重新又回到了add方法中,最后當(dāng)程序結(jié)束的時(shí)候add方法對(duì)應(yīng)的空間也會(huì)被銷毀,其中的變量、參數(shù)也會(huì)隨著被消失,為了方便大家理解這個(gè)過(guò)程,這里準(zhǔn)備了一張過(guò)程圖:

到這里為止,我們知道了在一個(gè)函數(shù)中運(yùn)行另外一個(gè)函數(shù),會(huì)在內(nèi)存中為這個(gè)函數(shù)開(kāi)辟一塊空間,當(dāng)這個(gè)函數(shù)執(zhí)行完畢之后,這塊空間會(huì)被計(jì)算機(jī)銷毀,重新回到之前的函數(shù)中,也就是說(shuō)在此之前,運(yùn)行的這個(gè)函數(shù)占據(jù)的空間一直存在,明白這個(gè)道理之后,我們?cè)俅位氐絼傞_(kāi)始的遞歸算法中。假設(shè)我們現(xiàn)在要計(jì)算3的階乘,那么在整個(gè)過(guò)程中,內(nèi)存的變化就可以這樣表示:

很顯然,隨著我們傳入的參數(shù)越來(lái)越大,整個(gè)過(guò)程會(huì)越來(lái)越復(fù)雜,而每次調(diào)用遞歸函數(shù)調(diào)用自身之后,都會(huì)在計(jì)算機(jī)中開(kāi)辟一塊新的空間,這說(shuō)明使用此種方法對(duì)系統(tǒng)的性能會(huì)有一定的影響,特別是當(dāng)我們遞歸執(zhí)行的次數(shù)很多的時(shí)候,特別容易造成系統(tǒng)崩潰。
以上就是動(dòng)力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Java基礎(chǔ)學(xué)習(xí):java中的遞歸算法”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)