那麼,我們都知道遞歸函數吧?但究竟是什麼使得函數遞歸?我在另一個問題(Lightening effect with javascript)的評論部分進行了一個小討論,這種討論質疑了我對遞歸函數的看法,但是這也給我留下了一個相當不令人滿意的缺乏正確定義的問題。遞歸的定義是什麼
我的遞歸函數個人的定義到目前爲止是如下:
函數是遞歸的,如果它直接或間接地調用自身
注:我將提供JavaScript代碼下面的例子,但我相信他們是非常普遍的。
對於這樣一個遞歸函數的簡單示例可以是這樣的:
function a() {
a();
}
而且此:
function a() {
b();
}
function b() {
a();
}
甚至這樣的:
function a() {
setTimeout(a, 1000);
}
那些功能單位計算的無除了我之外,任何事情都會因爲他們自己調用而仍然認爲它們是遞歸的。
出現的一件事是,第三個例子不是遞歸的,因爲它使用setTimeout
並且因此棧被解開。它也不是遞歸的,因爲從第次調用返回後,它不會控制第次調用。
有人提出了另一個觀點,那就是這些函數都沒有遞歸,因爲它們都不以遞歸方式計算實際問題。意味着一個問題必須通過將其分爲更小和更小的實例來解決。這裏引用維基百科文章:當一個函數是簡單的,往往較小版本的本身來定義 計算機編程
遞歸的例子。然後通過組合從較簡單版本的問題中獲得的解決方案 來設計該問題的解決方案。
所以這是遞歸的:
function fac(n) {
if (n <= 0) {
return 1;
}
return n * fac(n - 1);
}
但是這不會是:
function fac(n) {
if (n <= 0) {
return 1;
}
console.log(n);
fac(n - 1);
}
那麼,什麼是遞歸函數的恰當定義?究竟有沒有,還是真的只是一個哲學問題?函數必須具備哪些功能才能分類遞歸?
Good ol'Knuth。我還沒有聽說過這個。 – 2013-07-17 09:01:17
所以一個調用自身的函數,只是爲了增加一個計數器來遍歷一個平面數組,不會是遞歸的嗎? – basilikum
@basilikum,是的它會 - 它在數組末尾具有終止點,它具有根據「更簡單」函數定義的函數。由於棧是一個相當有限的資源,但它仍然是遞歸,就像'def sum(a,b)= sum(a + 1,b-1),如果b> 0,否則a'(對於無符號數當然)。不是一個聰明的方法來添加兩個數字,除非你只能增加或減少1,但它仍然是遞歸的。 – paxdiablo