編程基礎概念:遞推與遞歸

===》點我返回目錄《===

在進行計算的時候,經常會用到遞推的概念。遞推是一種用若干步可重複的簡運算來描述複雜問題的方法。通常是通過計算前面的一些項來得出序列中的當前項的值。

程序調用自身稱爲Recursive遞歸。它通常把一個大型複雜的問題層層轉化爲一個與原問題相似的規模較小的問題來求解,遞歸策略只需少量的程序就可描述出解題過程所需要的多次重複計算,大大地減少了程序的代碼量。

比如對斐波那契數列,我們看這個函數的定義,fib(n)的返回值是fib(n-1)+fib(n-2)。這個概念上很清晰,但是似乎陷入了死循環中無法出來了,所以一定要有一個出口,當n爲1和2的時候,我們要給他規定一個值。這就是遞歸的寫法。

你心裏肯定會問:那麼程序究竟是怎麼執行這個遞歸的呢?自己調用自己總是感覺奇奇怪怪的。

我們要再次打入計算機內部,來看一個普通函數是如何執行的。

一個函數,定義的時候,有一個名字,有輸入的參數,有返回的值,內部還要用到很多臨時的變量和指令。

計算機在調用一個函數的時候,會在一個叫做“棧”的內存空間爲這一次調用劃出一片空間來,存放本次函數調用用到的參數及內部變量。假如在執行函數體內部的時候,又碰到別的函數,同樣的辦法,在棧裏面再開闢一片新的空間,存放新函數用到的參數及內部變量。當這個新韓淑執行完畢後返回,計算機就把新開闢的這一片棧空間釋放,帶着返回值回到前個函數中斷的地方,前個函數的棧空間仍然存在,相當於程序執行返回到了以前的現場。

如果是遞歸的情況,自己調用自己,原理是一樣的,計算機爲第二次函數調用也是一樣地開闢一片新空間。跟調用別的函數沒有區別。

有一幅圖表達這個原理:

 

上圖演示了一個函數自己調用自己調了四遍。計算機內部開闢了四個空間,每個空間都是獨立保存了一份函數的現場(也叫執行上下文,包括參數變量等)。最後一次遞歸遇到終結條件就會返回上一級,這樣一級一級返回,直到初始調用處。

有了這幅圖景,我們可以看到,遞歸內部的實現跟普通函數沒有什麼區別。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章