CSI講義8:理解遞歸

所有的計算都是遞歸抖部;要理解遞歸首先要理解遞歸说贝。

艾舍爾版畫《手》

程序設計思想之一“遞歸”歷來是同學們的理解難點。據(jù)說慎颗,**要理解遞歸首先要理解遞歸! **當然乡恕,我們有更簡單的理解方法。比如俯萎,我們思考一個簡單的問題:給一個正整數(shù)n傲宜,求1+2+3+...+n的值。

重復強調以下算法設計原則:
1夫啊、明確輸入:正整數(shù)n函卒;
2、明確計算目標:1到n之間整數(shù)的累加撇眯;
3报嵌、設計處理過程。

當然熊榛,這么難的計算锚国,我們還不知道如何處理!即使我們不知道如何處理玄坦,大概也應該能寫出這樣的一個尚不知道處理流程的sum0函數(shù):

int sum0(int n){
計算累加并賦值給res血筑;
return res绘沉;
}

如果sum0是一個懶惰的家伙,他抗議說:嘿豺总,我可不是高斯车伞,我怎么會算這樣的東西?太難了喻喳!我只知道如果n==1的累加和另玖,就等于1!但是沸枯,如果你告訴我n-1之間整數(shù)的累和的答案res日矫,我倒是可以可以告訴你答案是:n+res! 這家伙真是天才赂弓。

于是我們只好去請另外一個家伙來算是n-1之間的累和绑榴,比如我找到的是sum1,給他一個整數(shù)n-1 盈魁。不可思議的是翔怎,sum1也同樣抗議,嘿杨耙,你幫我算出(N-1)-1之間整數(shù)的累和吧......于是我只好再去找sum2來做接下來的工作赤套。這樣的把戲持續(xù)下去值得有一個天才的輸入是1。如下所示:

sum0(5) ----> sum1(4) ----> sum2(3) ----> sum3(2)  ----> sum4(1) ---->1

如果我們要算的數(shù)是n==5珊膜,sum4接到任務的時候容握,輸入是5 - 4 == 1,他剛開口想說车柠,嘿剔氏,太難了,我......但是他只好閉嘴竹祷,因為求1到1之間數(shù)的累加就是1谈跛。好吧,sum4無奈地又沒好氣地對sum3說塑陵,答案是1感憾。這時候sum3也沒辦法偷懶了,因為他必須承擔自己的工作令花,告訴sum2答案阻桅,3。如此不斷地返回兼都,如下所示:

 15<---- sum0(5) <--10-- sum1(4) <--6-- sum2(3)  <--3-- sum3(2)  <--1-- sum4(1) 

值得注意的是嫂沉,這一群懶惰的家伙都一個德行而沒有任何差別:告訴我n-1為輸入的累和答案,我就告訴你n為輸入的累和答案俯抖。所以输瓜,作為雇主的話,也許我只需要雇傭一群sum0來干這項工作。因為sum0sum1(或其他任何一個sum)的處理過程沒有任何區(qū)別尤揣。于是工作流程就變成了:

sum0(5) ----> sum0(4) ----> sum0(3) ----> sum0(2)  ----> sum0(1) ---->1

15<---- sum0(5) <--10-- sum0(4) <--6-- sum0(3)  <--3-- sum0(2)  <--1-- sum0(1) 

既然所有的sum都一樣搔啊,我們只需要定義一個新的函數(shù)sum,如下:

int sum(int n){
    if(n == 1)
          return 1;
    return sum(n-1) + n北戏;//遞歸的返回點负芋!
}

以上講的都是設計思想,沒有涉及具體遞歸程序在計算機中的實現(xiàn)嗜愈。以下描述遞歸在計算機中的實現(xiàn)旧蛾,與教科書不同,為了幫助理解我們犧牲了一定的嚴謹性與準確性蠕嫁∠翘欤看完我這里的描述,希望大家還是要閱讀課本剃毒。

如果把sum程序編譯成機器可執(zhí)行的代碼病袄,我們一定會得到一個指令集,記為sum赘阀。sum(n)表示接受輸入為n的那段程序益缠,當他執(zhí)行到程序最后一句,它要調用自己“本身”基公,大家難理解的是所謂“本身”是什么幅慌。其實沒什么神秘的,如果我們用一種不怎么正確的理解方式轰豆,可以想象sum正常地去拷貝一份sum代碼出來放到內存的某個地方胰伍,給它輸入值n-1,然后等待sum(n-1)給它返回答案秒咨。這里的關鍵點是喇辽,把程序遞歸地調用自己看為對多個自己的代碼拷貝的調用。

還有一個關鍵點是雨席,sum(n-1)必須在返回值給sum(n)菩咨,這里稱為遞歸的返回點。為何一定會返回陡厘?注意抽米,sum程序一開始就設定了遞歸結束的條件n == 1 。每一次調用sum糙置,n的值都要減1云茸,根據(jù)Well-order principle(不懂就忽略,這里只是告訴你有這個東西)谤饭,必然會在某個時刻使得n到達1标捺,然后sum(1)把值返回給調用它的sum(2)懊纳。準確定義遞歸結束條件是寫遞歸程序首先需要考慮的問題。

注意亡容,return這個關鍵詞可不是只是返回一個值這么簡單嗤疯。程序應該如何在內存中駐留,程序該如何執(zhí)行闺兢,如何返回(return干了啥)等茂缚,這些都不不是本文的內容。請參看相關課本內容屋谭。

擴展一小步脚囊,把求n的累加變成求n-1的累加,也可以直觀地把這種思路理解為桐磁,當我們要解一個大的問題悔耘,我們可以把問題分解成小問題,然后根據(jù)小問題的答案來整合出整個大問題的答案所意。試試做以下思考:

作業(yè):
1淮逊、求n階乘:等于求n-1的階乘,再乘上n扶踊;
2、二分查找:把數(shù)據(jù)分為兩部分郎任,根據(jù)條件在某一部分進行檢索秧耗;
3、歸并排序:對n個數(shù)值進行排序等同于對兩次n/2數(shù)值的排序的歸并舶治;
4分井、GCD:求A和B的最大公因子,等于求更小數(shù)值B與A % B的GCD霉猛;

從解決問題的角度尺锚,遞歸的思想就是一種解決問題的方法,被廣泛地應用在程序設計中惜浅。說到嚴謹?shù)倪f歸理論瘫辩,其實,在高校不傳已久咯坛悉,《計算理論導引》有此方面的嚴格理論描述伐厌。

2017年7月整理

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市裸影,隨后出現(xiàn)的幾起案子挣轨,更是在濱河造成了極大的恐慌,老刑警劉巖轩猩,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卷扮,死亡現(xiàn)場離奇詭異荡澎,居然都是意外死亡,警方通過查閱死者的電腦和手機晤锹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門衔瓮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人抖甘,你說我怎么就攤上這事热鞍。” “怎么了衔彻?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵薇宠,是天一觀的道長。 經常有香客問我艰额,道長澄港,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任柄沮,我火速辦了婚禮回梧,結果婚禮上,老公的妹妹穿的比我還像新娘祖搓。我一直安慰自己狱意,他們只是感情好,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布拯欧。 她就那樣靜靜地躺著详囤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪镐作。 梳的紋絲不亂的頭發(fā)上藏姐,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音该贾,去河邊找鬼羔杨。 笑死,一個胖子當著我的面吹牛杨蛋,可吹牛的內容都是我干的兜材。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼六荒,長吁一口氣:“原來是場噩夢啊……” “哼护姆!你這毒婦竟也來了?” 一聲冷哼從身側響起掏击,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤卵皂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后砚亭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灯变,經...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡殴玛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了添祸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滚粟。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖刃泌,靈堂內的尸體忽然破棺而出凡壤,到底是詐尸還是另有隱情,我是刑警寧澤耙替,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布亚侠,位于F島的核電站,受9級特大地震影響俗扇,放射性物質發(fā)生泄漏硝烂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一铜幽、第九天 我趴在偏房一處隱蔽的房頂上張望滞谢。 院中可真熱鬧,春花似錦除抛、人聲如沸狮杨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽禾酱。三九已至,卻和暖如春绘趋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背颗管。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工陷遮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人垦江。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓帽馋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親比吭。 傳聞我的和親對象是個殘疾皇子绽族,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內容