有趣的遞歸(Recursion),一些直觀的示例

從前有座山,山上有座廟,廟裏有個老和尚在給小和尚講故事:「從前有座山,山上有座廟,廟裏有個老和尚在給小和尚講故事:……」javascript

反覆而糾結的定義

看完這個故事,對遞歸你已經有了印象,很好,這樣已足夠。若是你不幸是個喜歡精肯定義的人,那麼答案可能沒法讓你滿意:html

你想知道遞歸是什麼,你得先知道什麼是遞歸。To understand recursion, you must understand recursion.java

把你繞暈了沒有?你可能想這叫啥子定義喲。若是你去谷歌英文頁搜索「recursion」,谷歌就會給你來這麼一下:node

image

谷歌說:「你是說遞歸嗎?(Did you mean: recursion)」。編程

拼寫絕對是正確的,這不過是谷歌給你開的「遞歸式」的玩笑。瀏覽器

說完了谷歌,再說說必應(Bing),Bing是什麼意思呢:google

Bing = Bing is not google(Bing不是谷歌)spa

你仍是不滿意,那再看看GNU,GNU又是啥呢:.net

GNU = GNU’s Not Unix(GNU不是Unix)視頻

收斂的遞歸

好了,這些無限遞歸可能讓你有點煩悶了,讓咱們看點會收斂的(圖片來自google圖片搜索):

你是否想起了這樣的詩句:

你站在橋上看風景,看風景的人在樓上看你。明月裝飾了你的窗子,你裝飾了別人的夢。——卞之琳《斷章》

再來看看聽說是MIT計算機系的徽標:

MIT:MASSACHUSETTS INSTITUTE OF TECHNOLOGY 麻省理工學院(麻省:即馬薩諸塞州)

圖上有個lambda(λ),至於那個(Y F)=(F (Y F)),有沒有哪頭技術大奶牛知道它是啥呢?

不太清楚這玩意是啥~但公式可參見:http://en.wikipedia.org/wiki/Fixed-point_combinator#Y_combinator

另可參考mindhacks.cn上的這篇康托爾、哥德爾、圖靈——永恆的金色對角線(rev#2)(沒怎麼看懂~有興趣有精力的同窗可鑽研看看。)

自類似性(self-similarity)

下面是一顆天然界的徹底二叉樹(A complete binary tree in nature,來自http://www.cs.haifa.ac.il/~shlomit/,做者攝於非洲)

image

下圖爲芒德布羅集Mandelbrot set),分形(Fractal)理論中的一個概念:

這個圖很好體現了一種自類似性,實際上,不斷放大這個圖會發現模式在不斷重複。

來自優酷的這個視頻展現了這一點:http://v.youku.com/v_show/id_XMTc3NzIyMjI0.html

內容來自數學科教影片http://www.dimensions-math.org/Dim_ZH_si.htm(若是你有興趣,還有另外一部http://www.chaos-math.org/zh-hans

其它示例

艾舍爾版畫(來自http://www.guokr.com/blog/50805/

image

 

這裏的艾舍爾就是那本《哥德爾、艾舍爾、巴赫——集異璧之大成》(Gödel, Escher, Bach: an Eternal Golden Braid)中的艾舍爾了。見http://book.douban.com/subject/1291204/

我發現此書英文版竟然早在1979年就出版了,做者Douglas Hofstadter還取了箇中文名叫「侯世達」。

下圖則爲電影《盜夢空間》(Inception)中的一幕(其實這種場景在理髮店也很常見~):

image

電影情節中的夢中夢也很有遞歸的意味。

製造遞歸

若是你有個可移動的攝像頭,讓屏幕上播放攝像頭實時拍攝的畫面,而後拿着攝像頭對準屏幕,就能獲得相似下圖中的效果:

image

你能夠想一想,爲何會這樣呢?

與此類似的一個例子是音箱的爆音,在一些會場,有時會不當心把麥克風對誰了音箱,大功率音箱一開始存在一些很小的電流聲,這些聲音被麥克風捕獲又傳入音箱再次放大又傳到麥克風上……很快就會演變成刺耳的尖銳聲。

程序中的遞歸

文件夾的遞歸結構:

image

因此,用遞歸去處理這些是很常見的情形。相似的還包括那些有着樹形結構特色的如XML,HTML

以及Chrome瀏覽器中window對象的自指遞歸:

image

window對象是javascript在瀏覽器端的擴展中的全局對象(相似node.js中的global),它裏面又包含了一個名爲「window」的屬性指向它自身,因此能夠像上圖那樣無限展開。(遍歷處理這種結構須要特別當心,不然極可能會收到stack overflow的錯誤~)

以上談了很多的例子,都沒有涉及具體的編程,是想讓你們對遞歸有一個直觀的印象先,後面會談到一些經典的例子,如階乘以及菲波那契數列,還有用遞歸來作排序(如簡單的冒泡排序),最後將展現一個用遞歸方式來計算換零錢種數的例子(好比用100元,換成50,20,10,5,1元的組合總共有幾種),從中能夠體現遞歸的優點。因爲篇幅有限,這些將在後續篇章中談及。

相關文章
相關標籤/搜索