在編程學(xué)習(xí)中,大家常常會(huì)聽(tīng)到一個(gè)詞語(yǔ)——遞歸。遞歸是什么?遞歸函數(shù)又是什么?一個(gè)過(guò)程或函數(shù)在其定義或說(shuō)明中有直接或者間接調(diào)用自身的一種方法被稱為遞歸。
在經(jīng)過(guò)一段時(shí)間的編程學(xué)習(xí)后你對(duì)遞歸函數(shù)一定不會(huì)陌生,我們經(jīng)常需要用遞歸的方法來(lái)解決一系列復(fù)雜的問(wèn)題,遞歸算法對(duì)于大多數(shù)問(wèn)題都是很有效的,而且它很大程度上可以優(yōu)化我們的代碼。今天我們結(jié)合Scratch和Python來(lái)講一講遞歸函數(shù)。
當(dāng)我們想計(jì)算一個(gè)正整數(shù)的階乘時(shí)就可以應(yīng)用到遞歸的思想。首先用戶手動(dòng)輸入一個(gè)正整數(shù),計(jì)算它的階乘。方法有兩種,一種使用循環(huán)的思路,不用遞歸(圖1)。一種創(chuàng)建一個(gè)自制積木,使用遞歸的思想(圖2)。
用循環(huán)計(jì)算階乘
用遞歸計(jì)算階乘
第一種方法直接按階乘的概念計(jì)算容易理解。利用循環(huán)的方法完成n!=1×2×3×4……n。
使用第二種遞歸方法對(duì)于初學(xué)者理解上有一點(diǎn)困難,首先需要?jiǎng)?chuàng)建一個(gè)帶變量的自制積木,然后在自制積木中增加遞歸的終止條件(如果n=1那么停止腳本程序),然后才能實(shí)施遞歸的過(guò)程,并且在自制積木中增加積木自身——完成調(diào)用自身,最終程序會(huì)根據(jù)遞歸的方法一直運(yùn)行至終止條件才結(jié)束。
用Scratch的遞歸完成階乘計(jì)算后我們可以總結(jié)出以下三點(diǎn):遞歸是在函數(shù)中調(diào)用函數(shù)本身;由于調(diào)用函數(shù)需要較多計(jì)算機(jī)資源,所以遞歸的效率比較低,如果有時(shí)間限制不建議使用;遞歸過(guò)程中需要有一個(gè)明確的結(jié)束條件,即遞歸出口。
如果在Python中遇到需要使用遞歸函數(shù)時(shí),也需要在函數(shù)中調(diào)用函數(shù)本身。一定不要忘記增加停止的條件,如果不滿足條件就可以回到最外層調(diào)用的函數(shù)。
在學(xué)習(xí)遞歸函數(shù)時(shí)最經(jīng)典的問(wèn)題總是離不開(kāi)斐波那契數(shù)列和漢諾塔。大家可以搜索相關(guān)的知識(shí)點(diǎn),有很多利用遞歸方式來(lái)解決這些問(wèn)題的例子。
同樣是階乘的問(wèn)題給大家看看Python使用遞歸函數(shù)的解決方法(圖3)。
運(yùn)行效果如圖4。
我們通過(guò)Scratch和Python的遞歸函數(shù)解決了階乘問(wèn)題,接下來(lái)我們實(shí)戰(zhàn)一道藍(lán)橋杯中的遞歸題《母牛的故事》:有一頭母牛,它每年年初生一頭小母牛。每頭小母牛從第四個(gè)年頭開(kāi)始,每年年初也生一頭小母牛。請(qǐng)編程實(shí)現(xiàn)在第n年的時(shí)候,共有多少頭母牛?
假設(shè)我們正在藍(lán)橋杯的賽場(chǎng)上,拿到題目之后首先需要分析題目,找出題中的規(guī)律:前四年牛的數(shù)量為母牛每年年初生一頭小母牛,小母牛是不生的。第五年開(kāi)始小母牛也開(kāi)始生子。根據(jù)這樣的規(guī)律我們可以列出如圖5的表格,這樣就更方便我們尋找其中規(guī)律了。從表格中可以得出公式:a[i]=a[i-1]+a[i-3]。
然后用我們學(xué)過(guò)的Python的知識(shí),先定義列表,往list添加初始數(shù)據(jù),預(yù)處理每年母牛的數(shù)量,輸入年份,輸出數(shù)量。
遞歸是學(xué)習(xí)編程中必須克服的一個(gè)難點(diǎn),在今天有個(gè)初步了解后你可以查閱相關(guān)的資料完成斐波那契數(shù)列和漢諾塔的實(shí)例。