递归和尾递归

@[ToC]

递归

  • 递归就是一个函数直接或间接的调用自己.一般来说,递归需要有边界条件,递归前进段和递归返回段.当边界条件不满足的时,递归前进,当边界条件满足的时候,递归返回.
    递归就是在过程或者函数里调用自身.
    在使用递归策略时.必须有一个明确的递归结束条件,称为递归出口.
  • 递归一般用来解决三类问题:
  1. 数据的定义是按照递归定义的(Fibonacci函数,n的阶乘)
  2. 问题解法按递归实现(回溯)
  3. 数据的结构形式是按照递归定义的.(二叉树的遍历,图的搜索)

递归的缺点:
递归解题相对常用的算法如普通循环等,运行效率较低(所有的循环问题都可以用递归来解决).<font color ="red">在递归调用的过程当中系统为每一层的返回点,局部变量等开辟了栈来存储,因此递归次数过多容易造成栈溢出.</font>

使用线性递归来实现斐波那契

public  int fa(int n){
            if(n<2)
                return n;
            return fa(n-1)+fn(n-2);
        }
在这里插入图片描述

上面函数的执行过程.中间可以看出每一个函数都存在重复调用的情况.这个时候可以使用打表的方法来消除重复计算

public  int fa(int n, Map<Integer ,Integer> map){
            if(n==0 || n==1)
                return n;
            if(map.containsKey(n)){
                return map.get(n);
            }
            Integer put = map.put(n, fa(n - 1, map)+ fa(n-2,map));
            return n*put;
        }

测试也可以发现使用map后函数的执行时间减少了很多

尾递归

-<font color="red ">尾递归就是把当前的运算结果放在参数传给下层函数,使用尾递归可以减少堆栈的占用量.</font>
如上面的代码可以写成

public static int fa2(int n,int ret1,int ret2){
        if(n==0)
            return ret1;
        return   fa2(n-1,ret2,ret1+ret2);
    }

如果n=5 ,ret1=0 ,ret2=1;

在这里插入图片描述

从图中可以看出,尾递归不需要向上返回了,但是需要引入两个参数来保持运算结果.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值