函数-递归调用

一、什么是递归调用

递归调用:在函数调用过程中,直接或间接地调用了函数本身,这就是函数的递归调用1.递归的优点

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000)

2.递归的缺点

解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

3.递归案例



#阶乘计算
def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)
分析
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120

4.二分法

#二分法
l = [1, 2, 10,33,53,71,73,75,77,85,101,201,202,999,11111]

def search(find_num,seq):
    if len(seq) == 0:
        print(‘not exists‘)
        return
    mid_index=len(seq)//2
    mid_num=seq[mid_index]
    print(seq,mid_num)
    if find_num > mid_num:
        #in the right
        seq=seq[mid_index+1:]
        search(find_num,seq)
    elif find_num < mid_num:
        #in the left
        seq=seq[:mid_index]
        search(find_num,seq)
    else:
        print(‘find it‘)

  

  

 
时间: 2024-10-05 08:00:25

函数-递归调用的相关文章

函数递归调用过程中的调用堆栈的情况

为了加深对函数递归调用过程中的理解,本Demo程序特意在VS2008 C#控制台程序实现了阶乘的计算功能,用于观察函数递归调用过程中的调用堆栈的情况. 源码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace RecursiveTset { class Program { //阶乘的定义:n!=n*(n-1)!,特别的,1!=1:0!=1 //阶乘的实

shell函数递归调用实现目录的对比拷贝

目的与需求: 在移植时,需要将根文件系统rootfs1中的新增内容合入rootfs2,但不能覆盖rootfs2中原有的东西.即只能比较两个文件系统的异同,将1中比2中多出来的东西移到2中. 难点: 目录中若有相同的子目录,也要使得子目录满足上述需求. 点睛之笔: shell 递归调用, 借鉴二叉树的深度优先遍历. 实操: 1 #!/bin/bash 2 3 cpdifffile() 4 { 5 6 DIR1=$1 7 DIR2=$2 8 files1=`ls $DIR1` 9 #files2=`

python 关于函数递归调用自己

爬取b站博人传 每页短评20个,页数超过1000页, 代码如下 import requests import json import csv def main(start_url): headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36',} res = requests.

函数递归调用

int main(int argc, const char * argv[]) { f(1,1,1000); return 0; } void f(int a,int b,int n) { if (a<n) { printf("%d\n",a); a=a+b; f(b,a,n); } else { printf("stop\n"); } }

C新手求助函数递归调用的理解!!很急!!

102klj寐滦宜陨咏腊<http://weibo.com/p683p410p/230927983046756163919872> wn8h3a揽埔悄状鼗埠<http://weibo.com/p108p588p/230927983024178431004672> wii6dd秆院郴罕幻脊<http://weibo.com/p753p931p/230927982698091037593600> qa0qw9醇桓娜赜凡诜<http://weibo.com/lwncwQ

JavaScript函数之实际参数对象(arguments) / callee属性 / caller属性 / 递归调用 / 获取函数名称的方法

函数的作用域:调用对象 JavaScript中函数的主体是在局部作用域中执行的,该作用域不同于全局作用域.这个新的作用域是通过将调用对象添加到作用域链的头部而创建的(没怎么理解这句话,有理解的亲可以留言告诉我, 谢谢).因为调用对象是作用域链的一部分,所以在函数体内可以把这个对象属性作为变量来访问. 调用对象的属性包括:用var声明的局部变量,函数形参,还有一种特殊的属性arguments 函数的实际参数:实际参数对象 arguments对象,用来引用实际参数对象.函数的arguments对象并

(转载)你好,C++(27)在一个函数内部调用它自己本身 5.1.5 函数的递归调用

你好,C++(27)在一个函数内部调用它自己本身 5.1.5 函数的递归调用 5.1.5 函数的递归调用 在函数调用中,通常我们都是在一个函数中调用另外一个函数,以此来完成其中的某部分功能.例如,我们在main()主函数中调用PowerSum()函数来计算两个数的平方和,而在PowerSum()函数中,又调用Power()函数和Add()函数来计算每个数的平方并将两个平方加和起来成为最终的结果.除此之外,在C++中还存在另外一种特殊的函数调用方式,那就是在一个函数内部调用它自己本身,这种方式也被

你好,C++(27)在一个函数内部调用它自己本身 5.1.5 函数的递归调用

5.1.5 函数的递归调用 在函数调用中,通常我们都是在一个函数中调用另外一个函数,以此来完成其中的某部分功能.例如,我们在main()主函数中调用PowerSum()函数来计算两个数的平方和,而在PowerSum()函数中,又调用Power()函数和Add()函数来计算每个数的平方并将两个平方加和起来成为最终的结果.除此之外,在C++中还存在另外一种特殊的函数调用方式,那就是在一个函数内部调用它自己本身,这种方式也被称为函数的递归调用. 函数的递归调用,实际上是实现函数的一种特殊方式.当递归函

Java递归调用实例

private int num=0; private String parentCode = null; private String returnCode = null; /** * 查询顶级外场,如果当前部门的上级部门一直是外场,那就返回最顶层的orgcode,如果一直不是外场,就返回最初的orgcode, * 如果中间有一个是外场,并且它的父级部门不是外场,就返回是外场的部门code..然后根据returnCode查找这个部门下的所有部门 * sql中主要使用where--contact-