递归算法

一.递归相关内容

        递归是指在函数中调用函数自身的方法。这一方法通常就是将一个复杂的问题逐渐拆解成一个个小问题,然后再对其进行总和,从难到易,再通过回溯,由此得出答案。

        递归模板(这里以求斐波那契数列为例)

int fi(int x)    // 参数
{
    if(x==1) return 1; // 判断条件 何时返回函数调用
    if(x==2) return 1;
    return fi(x-1)+fi(x-2); // 返回值 (函数需要执行的功能)
}

通过上述模板,可以了解到递归函数分为三个部分

1.调用函数时的参数:递归函数需要通过相关参数不断调用函数自身求得答案。

2. 判断条件(结束条件):递归函数不断调用自身(如果一直调用,则陷入死循环中)因此需要找出终止条件,退出对函数的自身调用,达到递归的目的。

3.函数执行的功能(找出等价关系式):每个问题不一样,对应的递归函数也不一样,需要找出其关系式,通过递归的形式写出。

二.递归相关的典型例题

1.求 n 的阶乘的问题

阶乘式: F(n)=n! 递归的关系式(拆成小问题的形式):F(n)=n*F(n-1)

注:这里 F(n) 仅与 F(n-1) 构成关系,若写成 F(n)=n*(n-1)*F(n-2) 则包括了前面的关系式。

结束条件: F(1)=1 当 n 为 1 时 返回 1     

以图画的形式展开递归的内容

核心代码

int fi(int x)
{
    if(x==1) return 1;
    return n*fi(x-1);
}

2.求斐波那契数列

例如 1 1 2 3 5 8 13 21 34 55 89 144 的这一类数,规定前两个数是 1 ,从第三个数开始每个数是前两个数的和。

关系式: F(n)=F(n-1)+F(n-2)       这里则是将F(n) 分成了两个子问题,分别对F(n-1) 和 F(n-2) 求解

结束条件:规定 F(1)=1,F(2)=1

图示

 核心代码

int fi(int x)
{
    if(x==1) return 1;
    if(x==2) return 2;
    return fi(x-1)+fi(x-2);
}

一个关于递归的思考:在上图中,可以看到F(1) F(2) 反复被递归调用,如果当n取得非常大,F(1) F(2)被重复调用的次数将会更多,从而使效率大大降低,有没有什么方法可以避免重复调用?(将在后文解答)

3.跳台阶问题

小明一次可以跳1~3个台阶,问他跳 n 个台阶时,有几种方法?

当调至n个台阶的前一个阶段有三种情况:在 n-1 个台阶处 跳 1 格  

                                                    在 n-2 个台阶处 跳 2 格

                                                    在 n-3 的台阶处 跳 3 格

得出关系式 F(n)=F(n-1)+F(n-2)+F(n-3) 

结束条件: F(1)=1 F(2)=2 F(3)=4  

大致过程与题2相同,不再论述

三.关于递归的思考

        递归是通过不断调用自身函数求得结果的过程,在这其中总是会出现重复调用的情况,从而使代码超时,怎样才可以避免这种情况,达到高效的目的呢?

 方法:只需要将计算过的值记录下来,当再次遇到相同的情况时,可以直接输出相应的数,从而减去了不必要的重复递归操作。

这里以T2为例:

int fi(int x)
{
    if(x==1) return 1;
    if(x==2) return 1;
    if(f[x]) return f[x]; // 如果 f[x]被记录过,则可直接输出,从而将递归操作变为线性的结构
    f[x]=fi(x-1)+fi(x-2);
    return f[x];
}

四.总结

1.递归的难度不在于代码的复杂程度,递归总是通过简单的代码解决复杂的问题,针对于解决递归的问题,核心为寻找递归的关系式以及结束条件,就可以解决问题。

2.对于递归的内涵,可以通过调试的方法(单步进入),探寻递归的本质2.

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值