美文网首页NOIP之路
【语法篇】14、浅谈递归函数

【语法篇】14、浅谈递归函数

作者: 沧海无雨 | 来源:发表于2017-02-23 09:04 被阅读28次

    一、什么是递归

    其实上节课讲到函数的最后,我们打了一个比方:把主程序中的顺序比喻成正常的时间顺序,遇到函数调用,即相当于做梦,可以跳出当前时空,做完梦之后又会回到做梦的时空处。有一些“梦”会比较有意思,在梦里继续做了同样的梦,这就叫做递归。
    我们用最最浅显易懂的一个故事来说明:

    老和尚讲故事

    从前有座山,山里有座庙,庙里有个老和尚,在给小和尚讲故事。讲的什么故事呢?从前有座山,山里有座庙,庙里有个老和尚,在给小和尚讲故事。讲什么故事呢?从前有座山,山里有座庙,庙里有个老和尚,在给小和尚讲故事。讲的什么故事呢?从前有座山,山里有座庙,庙里有个老和尚,在给小和尚讲故事。。。。。。

    说白了,就是自己调用自己,函数调用函数,再举一个比较饶舌的例子,关于递归的定义。

    递归:
    参见递归。
    很迷糊,对吧,好吧,再具体一些。
    递归:
    如果还是没有明白递归是什么意思,参见“递归”。

    其实说白了,就是“自己用自己”。在数学函数中,递归往往会很简单,有助于理解,譬如我们熟悉的阶乘运算,f(n)=n!,一般在数学上就定义成:
    {
    f(0)=1
    f(n)=f(n-1) * n (n>=1)
    }
    如果我们用代码来实现一下,那是再简单不过的事情了。

    #include <iostream>
    using namespace std;
    
    long long f(int x){
        if(x==0)
              return 1;
        return f(x-1) * x;
    }
    
    int main(){
      int n;
      cin>>n; // 此处n的规模应该很小,再大的话,需要考虑高精度算法
      cout<<(long long) f(n);  //暂时不考虑太大的数据
      return 0;
    }
    

    其实基本上就是照抄数学表达式,因此递归函数的关键在于理清思路,明确数学表达式,稍微要注意的一个问题时,递归一定要写清楚“终止条件”,像上面的例子,终止条件是x==0,如果没有终止条件,函数将无限递归......
    如果对上面阶乘递归还不过清楚的话,可以参看下面的一个比喻:

    皇帝(main函数):大臣,你给我算一下f(3)。
    大臣(调用f(3)的那个函数):知府,你给我算一下f(2)。
    知府(调用f(2)的那个函数):县令,你给我算一下f(1)。
    县令(调用f(1)的那个函数):师爷,你给我算一下f(0)。
    师爷(调用f(0)的那个函数):回老爷,f(0)=1。
    县令:回知府大人,f(1)=1。
    知府:回大人,f(2)=2。
    大臣:回皇上 ,f(3)= 6。
    最终得到了结果,皇上满意了。

    最后要注意的是,递归对我们理清思路和理解代码非常简单,但是反复的调用,对计算机的运算是一个噩梦,而且在递归运算中,往往会反复递归,反复运算,拜拜耗费大量的时间,另外从时间花销上,递归函数无疑是一个不太好的函数,对于运算次数较多(递归深度较深)时,我们往往不用递归,因为一般都会超时。


    二、练习

    1、斐波那契数。
    2、输入一个非负整数,输出它的逆序数。如123,输出321。

    相关文章

      网友评论

        本文标题:【语法篇】14、浅谈递归函数

        本文链接:https://www.haomeiwen.com/subject/dkmvwttx.html