递归函数两种方式的区别
概述
遞歸函數(shù)都不陌生,比如計(jì)算n的階乘:
function f($n){if($n <= 1) return 1;return $n * f($n-1); }當(dāng)然,有人可能會(huì)這么寫(xiě):
function f($n, $result){if($n <= 1) return $result;return f($n-1, $n*$result); }上面兩種方式看著好像沒(méi)什么區(qū)別,但是在cpu眼中,可就不一樣了。
分析
函數(shù)在調(diào)用的時(shí)候會(huì)開(kāi)辟一塊函數(shù)棧,用來(lái)保存函數(shù)的局部變量、參數(shù)、上一個(gè)棧的指針、返回值等信息,當(dāng)函數(shù)調(diào)用結(jié)束后會(huì)銷(xiāo)毀。遞歸函數(shù)會(huì)一直遞歸下去,上層的函數(shù)棧一直不會(huì)銷(xiāo)毀,知道遞歸結(jié)束,全部退出。
舉個(gè)栗子,當(dāng)調(diào)用f(3)的時(shí)候,對(duì)于上面的第一種情況,函數(shù)棧大概長(zhǎng)這樣(僅保留參數(shù)和返回值,忽略其他內(nèi)容):
文字描述就是:
f(1)=1
f(2)=2*f(1)=2*1=2
f(3)=3*f(2)=3*2=6
f(4)=4*f(3)=4*6=24
也就是每一次調(diào)用,都會(huì)保存本次的變量n以及遞歸調(diào)用的返回值,這就會(huì)導(dǎo)致如果遞歸的太神,就會(huì)開(kāi)辟太多的內(nèi)存。
如果使用第二種寫(xiě)法,會(huì)有什么不同么?
套用剛才的分析,先用文字描述一下:
f(4, 1)=f(3, 4*1)=f(2, 3*4)=f(1, 2*12)=24
有沒(méi)有發(fā)現(xiàn)區(qū)別,區(qū)別就是,前一種寫(xiě)法要保存一個(gè)局部變量n,而后一種寫(xiě)法,都寫(xiě)到下一個(gè)方法的參數(shù)中了。也就是說(shuō),第二種方式,可以直接返回下層方法,不需要退回去了。當(dāng)然,cpu發(fā)現(xiàn)這種情況,會(huì)復(fù)用函數(shù)棧,也就是說(shuō),函數(shù)棧大概是這么個(gè)情況:
看著好像也沒(méi)啥區(qū)別,但是!因?yàn)榭梢灾苯臃祷?#xff0c;上圖的四個(gè)棧使用的都是同一個(gè)棧。
當(dāng)遞歸返回的是遞歸調(diào)用,并且講調(diào)用直接返回,沒(méi)有參與運(yùn)算等,就會(huì)被這樣優(yōu)化,復(fù)用棧。
總結(jié)
以上是生活随笔為你收集整理的递归函数两种方式的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 计算矩阵中全1子矩阵的个数
- 下一篇: bootstrap上传图片可实现查看上一