递归调用

来源:互联网 发布:ios wkwebview 传值js 编辑:程序博客网 时间:2024/04/30 14:36

今天cf遇见了一点问题,是自己学过却不怎么熟悉的递归调用。

    递归定义使人们能够用有限的语句描述一个无穷的集合。C++语言允许一个函数体中出现调用自身的语句,成为直接递归调用。也允许被调用的另一个函数反过来调用原函数,策划功能为间接递归调用。这种功能为递归结构问题提供了求解的实现手段,使程序语言的描述与问题的自然描述完全一直,因而使程序易于理解、易于维护。

    通过简单的例子说明递归函数的构成规律和执行过程。

    使用递归函数编程序求n!

    当n>=0时,阶乘可以用循环迭代(非递归)计算:

fact=1;for(int k=n;k>=1;k--)fact*=k;

也可以用另一种递归形式定义阶乘:


    阶乘的递归定义把问题分为两部分,一部分用已知的参数n作为被乘数,另一部分使用原来的阶乘定义作为参数。不过,乘数n*(n-1)的规模变小了,以此类推,问题的规模进一步缩小,从而产生越来越小的问题,最后归结到基本情况,0!=1。C++函数调用能够识别并处理这种基本情况,向前一个函数调用并返回结果,并回溯一系列的中间结果,直到把最终结果返回给调用函数。

    以下程序在main函数中调用求阶乘的递归函数。

#include<iostream>using namespace std;long fact(int n){if (n == 0)return 1;elsereturn n*fact(n - 1);}int main(){int n;cout << "Enter n(n>=0):";cin >> n;cout << n << "!="<<fact(n) << endl;return 0;}

    递归函数执行由递推和回归两个过程完成。递归函数之所以能够实现,关键是系统使用堆栈来保存函数调用中的传值参数、局部变量和函数调用后的返回地址。函数自身调用进行递推:系统把有关参数和地址压进堆栈,一直递推到满足终止条件,找到问题的最基本模式为止。然后进行回归:系统从堆栈中逐层弹出有关参数和地址,执行地址所指向的代码,一直到栈空为止,得到问题的解。

    递归调用与一般函数调用,堆栈管理的操作过程是一致的。不同的是,函数的自身调用就像是产生多个正在运行(等待结束)的相同函数副本。如果这种调用不能终止并产生副本,将是程序十分严重的错误。

    构成递归函数有两个基本要素:

    描述问题规模逐步缩小的递归算法;

    描述基本情况的递归 终止条件。

     在fact函数中,递归调用的语句为:

    t=n*fact(n - 1);
由调用参数n-1,使问题规模逐渐缩小,直至到达递归带哦用终止条件:

    n==0
    返回基本情况值1.

    在程序中,递归算法和递归条件通常用条件语句表达。递归调用可以出现在语句中,也可以出现在判断表达式中。



0 0
原创粉丝点击