所以,我们都知道递归函数,对吧?但究竟是什么使函数递归?我在另一个问题( Lightening effect with javascript )的评论部分进行了一次小讨论,这挑战了我对递归函数的看法,但它也让我对缺乏正确的定义感到非常不满意。
到目前为止,我个人对递归函数的定义如下:
如果函数直接或间接调用自身,则它是递归的
注意:我将为以下示例提供 JavaScript 代码,但我确信它们非常通用。
这种递归函数的一个简单示例可能是:
function a() {
a();
}
还有这个:
function a() {
b();
}
function b() {
a();
}
甚至这个:
function a() {
setTimeout(a, 1000);
}
这些函数都没有计算任何东西,但我仍然认为它们是递归的,因为它们调用了自己。
出现的一件事是,第三个示例不是递归的,因为它使用setTimeout
并且因此堆栈被展开。它也不是递归的,因为从n
th 调用返回后,它不会将控制权交还给n-1
th 调用。
提出的另一点是,这些函数都不是递归的,因为它们都不以递归方式计算实际问题。这意味着必须通过将问题划分为越来越小的实例来解决问题。这里引用的维基百科文章:
当一个函数被定义为更简单、通常更小的自身版本时,计算机编程中的递归就是一个例子。然后通过组合从问题的更简单版本获得的解决方案来设计问题的解决方案。
所以这是递归的:
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);
}
那么递归函数的正确定义是什么?有没有,还是真的只是一个哲学问题?一个函数必须具备哪些特征才能被归类为递归的?