循環(huán)和遞歸的區(qū)別在于是否在迭代運(yùn)算體內(nèi)部決定迭代結(jié)束。
就像兩個(gè)小孩子玩球。玩一輪如果很開心,就再玩一輪。在某一輪兩個(gè)人吵起來了,打起來了。
遞歸是兩個(gè)小孩子自己決定,哼,玩不下去了,不玩了,滾。
循環(huán)是旁邊一直坐著個(gè)大人,看到兩個(gè)小孩子一輪玩得開心,就讓他們繼續(xù)玩下一輪??吹剿麄兂称饋砹?,就把他們分開,結(jié)束玩球游戲。
尾遞歸就是在每一輪游戲的“完全結(jié)束”才(調(diào)用自己)開始下一輪游戲。每一輪游戲都是完結(jié)的,相關(guān)數(shù)據(jù)(比分之類的)在每一輪都已經(jīng)結(jié)算清楚。
不能夠改寫成尾遞歸的遞歸是因?yàn)槊恳惠喍贾煌娴揭话刖屯嫦乱惠喠恕5扔螒虻淖詈笠惠喭瓿珊螅惠営忠惠喌赝刈?,把之前沒完成的游戲玩完。為什么這樣呢?因?yàn)槊恳惠喴婧?,需要下一輪游戲的?shù)據(jù)(第n輪的游戲需要n+1輪的數(shù)據(jù)來決定第n輪的結(jié)果)。這玩意兒是比較難理解,因?yàn)槲覀儸F(xiàn)實(shí)生活的時(shí)間是不可倒退的??梢源騻€(gè)比喻——
一個(gè)女孩子在考慮是否和一個(gè)男生在一起,男生說即使在他死那天,他還會(huì)愛著她。女生想:我能相信他明天還會(huì)愛我,如果他后天還會(huì)愛我。我能相信他后天還會(huì)愛我,如果他大后天還愛我。即,因?yàn)橄嘈潘趎+1天會(huì)愛我,我就能相信他第n天是會(huì)愛我的。既然這樣,那從他死那天往回走,他每天都是愛我的,那他后天,明天,今天都是愛我的。
再換回兩個(gè)小孩子玩球的游戲里。在兩個(gè)人吵起來的最后一輪,如果是循環(huán)(大人喊結(jié)束游戲)或者尾遞歸(小孩子自己決定結(jié)束游戲),整個(gè)玩球活動(dòng)都到處結(jié)束,如果需要,可以直接返回比分。
而在不能重構(gòu)成尾遞歸的遞歸里,兩個(gè)小孩子在最后一輪決定不繼續(xù)玩后,想起上一輪還沒玩完“哎,上一輪你還欠我兩個(gè)球,來來來,我們返回到上一輪的環(huán)境里繼續(xù)玩”。這樣一直返回,直到開局的第一輪,最終得出最后比分。
這也是為什么遞歸比循環(huán)更耗資源,因?yàn)槊恳惠喭媲虻纳舷挛?命名空間)都要保存下來,以便在最后一輪結(jié)束后往回走的時(shí)候可以繼續(xù)之前沒玩完的流程繼續(xù)走下去玩完當(dāng)輪游戲。