Math 递归不仅仅是一个调用自身的函数

Math 递归不仅仅是一个调用自身的函数,math,recursion,computer-science,Math,Recursion,Computer Science,我看过的每本关于递归函数的教科书都使用阶乘 作为一个例子,这是有益的,但不是完全说明 出于编程目的,递归函数能否以函数为基础 在这种情况下,它可以在其主体中包含其他函数调用,还是可以执行 在不同的递归级别上不同 如果它做了这些事情,它仍然是一个“递归函数”吗 或者它现在是别的什么了?递归函数的定义就是“一个调用自身的函数”。所以,如果你有一个调用自身的函数,它就是一个递归函数 任何其他功能都取决于您使用的语言的功能。递归函数是一个在其体中调用自身一次或多次的函数。函数也可以是相互递归的,其中一个

我看过的每本关于递归函数的教科书都使用阶乘 作为一个例子,这是有益的,但不是完全说明

出于编程目的,递归函数能否以函数为基础 在这种情况下,它可以在其主体中包含其他函数调用,还是可以执行 在不同的递归级别上不同

如果它做了这些事情,它仍然是一个“递归函数”吗
或者它现在是别的什么了?

递归函数的定义就是“一个调用自身的函数”。所以,如果你有一个调用自身的函数,它就是一个递归函数


任何其他功能都取决于您使用的语言的功能。

递归函数是一个在其体中调用自身一次或多次的函数。函数也可以是相互递归的,其中一个函数是根据第二个函数定义的,反之亦然

我已经编程20多年了,不需要递归。让我真正理解递归调用的需要和美妙之处的是Scheme语言,以及像《小Schemer》这样的书


并非所有编程语言都在同一级别支持递归。Scheme是做得很好的人之一。Python更是如此。因此,如果您想深入研究递归,请检查您的编程语言的能力。

这是一个非常简单的递归函数示例,它只需将集合(表示为堆栈的数组)中的所有值输出到浏览器控制台,然后使用.pop()方法将它们从堆栈中弹出

totalSize值在整个调用堆栈中不会改变,因此可以通过将当前堆栈大小除以原始大小来测量中间点

要回答在递归的不同层次上它的行为是否会有所不同的问题,答案是肯定的:

// a simple array of 10 items
var coll = [1,2,3,4,5,6,7,8,9,10];

// recursive function that calls itself. It behaves slightly different at
 // the halfway point
function test(totalSize, col) {
    if(col == undefined || col.length == 0) {
        return 0;

     } else {
        if(col.length / totalSize < .5) {
            console.log("Past 1/2 way point!");
        }
        console.log("total = " + totalSize);
        console.log("col.pop() = " + col.pop());
        return test(totalSize, col);
    }
}

// make a call to the function with the total size and the collection
test(coll.length, coll);
//一个包含10项的简单数组
var coll=[1,2,3,4,5,6,7,8,9,10];
//调用自身的递归函数。它的行为在不同的时间略有不同
//中点
功能测试(总尺寸,col){
如果(列==未定义| |列长度==0){
返回0;
}否则{
如果(列长/总尺寸<.5){
log(“超过1/2个路径点!”);
}
console.log(“total=“+totalSize”);
log(“col.pop()=”+col.pop());
返回测试(总尺寸,col);
}
}
//使用总大小和集合调用函数
试验(coll.长度,coll);
此外,您还询问是否可以调用其他函数,这也是可能的。在下面的示例中,使用函数返回基本情况的结果, 函数用于抽象中间点行为:

// a simple array of 10 items
var coll = [1,2,3,4,5,6,7,8,9,10];

// recursive function that calls itself. It behaves slightly different at
 // the halfway point
function test(totalSize, col) {
    if(col == undefined || col.length == 0) {
        return handleBaseCase(totalSize, col);

     } else {
        // handle if it's at 1/2 way point
        handleHalfwayPoint(totalSize, col);  

        console.log("tital = " + totalSize);
        console.log("col.pop() = " + col.pop());
        return test(totalSize, col);
    }
}

function handleHalfwayPoint(totalSize, collection) {
    if(collection.length / totalSize < .5) {
        console.log("Past 1/2 way point!");
    }
}

// instead of returning 0, return "Done" and also print to the log
function handleBaseCase(totalSize, collection) {
    console.info("Done!");
    return "Done!";
}

// make a call to the function with the total size and the collection
test(coll.length, coll);
//一个包含10项的简单数组
var coll=[1,2,3,4,5,6,7,8,9,10];
//调用自身的递归函数。它的行为在不同的时间略有不同
//中点
功能测试(总尺寸,col){
如果(列==未定义| |列长度==0){
返回车把箱(总尺寸,col);
}否则{
//如果在1/2路径点,则进行处理
handleHalfwayPoint(总尺寸,col);
console.log(“tital=“+totalSize”);
log(“col.pop()=”+col.pop());
返回测试(总尺寸,col);
}
}
功能手柄中途点(总尺寸、集合){
如果(收集长度/总尺寸<.5){
log(“超过1/2个路径点!”);
}
}
//返回“完成”并打印到日志,而不是返回0
功能车把箱(总尺寸,系列){
console.info(“完成!”);
返回“完成!”;
}
//使用总大小和集合调用函数
试验(coll.长度,coll);
虽然这些特定的例子不能解决任何实际问题,但它展示了在另一个函数中调用函数的概念如何扩展以处理其他用例。教科书中的示例只是为了教您递归的基础知识,并帮助您掌握将来处理更复杂的实际问题所需的工具


因为这种函数式语言是JavaScript,所以运行它们的障碍很低。您可以通过在Chrome开发者控制台中运行代码来尝试这些示例,也可以在一个小的测试HTML文件中运行它们。祝你好运

正如其他答案所说,递归函数是一个调用自身的函数。如前所述,有两种类型:

  • 直接递归:函数调用自身的过程
  • 间接递归:当一个函数不是由它自己调用,而是由它调用的另一个函数(直接或间接)调用时

  • 我在你的问题中看到了数学标签。递归与数学归纳法有关。如果你证明它可以解决基本情况,然后你证明如果无限语句序列中的任何一条语句是真的,那么下一条语句也是真的,那么你证明它在任何情况下都可以解决问题。

    递归函数只不过是一个调用自身的函数。就这样。你所说的“将函数作为其基本情况”是什么意思?我想,举个例子,你会有一个函数,它接受一些输入,并以某种方式将它们转换为输出。然后你会有第二个函数调用第一个函数并修改它的输出,然后在它自己的输出上调用它自己,可能使用case-switch语句,或者使用不同输入的不同行为,诸如此类?在这片土地上真的很新鲜,只是试着去感受一下。有趣的问题!关于第2部分,“它是否包括其他函数调用”,答案肯定是肯定的:例如,您甚至可以调用调用第一个函数的另一个递归函数,即。参见。的答案。“我已经编程20多年了,不需要递归。”因此您从未编写过递归下降解析器,或者使用树数据结构,或者使用快速排序/二进制搜索/merg