C语言
递归就是在定义函数的同时也使用了该函数本身,我们通过例子来体会:
Example 1: 阶乘
//阶乘
#include<stdio.h>
int factorial(unsigned int i){
if(i<=1){
return 1;
}
return i*factorial(i-1);
}
int main(){
printf("%d",factorial(5));
return 0;
}
输出:
120
比较好理解吧,像是定义了一个 factorial() 函数,直接调用函数名即可
Example 2:斐波那契数列

依据我们的数学知识,给出前几项就可以通过递归得到任意一项了
C++
直接调用自己或通过其它函数间接调用自己的函数称为递归函数。
递归函数适合于求解递归问题,所谓递归问题:是指一类比较复杂的问题,其问题的解决又依赖于类似问题的解决,只不过后者的复杂程度或规模较原来的问题更小,而且一旦将问题的复杂程度和规模化简到足够小时,问题的解法其实非常简单。
例如,计算某个自然数 n 的阶乘的公式写为:
n!=n×(n−1)×(n−2)×…×2×1
这种阶乘的计算用如下循环结构来实现:
int factorial = 1;
for (int counter=1; counter <= n; counter ++)
{
factorial=factorial * counter;
}
也可以从另外一个角度来看待阶乘的计算,n 的阶乘可以通过递归定义为:
n!=n×(n -1)! (n>1)
n!=1 (n=1)
例如为了计算5!,要先计算出4!,要计算4!,又要先计算出3!,要计算3!,则要先计算2!,而2!又需要先计算1!。
根据定义,1!为1,有了1!就可以计算2!了,有了2!的结果就可以计算出3!的值,有了3!的值就可以算出4!的值,最后可以得到5!的结果。
从上述递归计算过程可以看到,一个复杂的问题,被一个规模更小、更简单的类似的问题替代了,经过逐步分解,最后得到了一个规模非常小、非常简单的、更容易解决的类似的问题,将该问题解决后,再逐层解决上一级问题,最后解决了较复杂的原始的问题。
递归性质
对于递归函数而言其调用过程与一般函数的调用过程完全一样,同时函数的递归调用具有下面两个性质:
- 函数调用时,调用程序在函数调用处暂时挂起,程序控制离开调用程序转入被调用函数执行,只有当被调用函数执行完后,才返回到调用程序的调用处继续向下执行,所以调用函数一定要在被调用函数执行完成后才能继续执行并结束。由于递归调用中调用函数和被调用函数可能是同一个函数,同一个函数的两次调用可以理解为函数的两个不同的副本;
- 一个函数被调用,系统会为该函数的这次执行分配存储空间,包括为该函数的形式参数和局部变量分配单元。因此,递归函数执行时,在某一时刻,计算机内可能有该递归函数的多个活动的同时存在,每个活动(即函数的每次调用执行)都有自己对应的存储空间,也就是说,函数的形式参数和局部变量,在函数的每次调用执行中都有不同的存储空间。
使用递归函数求阶乘的程序为:
#include <iostream>
using namespace std;
int fac(int num)
{
if (num <= 1) // 递归终止,直接给出结果
return 1;
else // 递归调用
return (num * fac(num - 1));
}
int main()
{
int i;
cin >> i;
cout << i << "! = " << fac(i) << endl;
return 0;
}
例子:
输入一个正整数,然后把该整数的每一位数字从高位到低位顺序输出,每个数字占一行。
例如:输入:123,程序输出:
1
2
3
递归代码:(用到了构造函数)
#include <iostream>
#include <cstdio>
using namespace std;
void splitNum(unsigned int n)
{
if(n>=0 && n<=9)
cout<<n<<endl;//单独考虑一位数
else{
if(n/10>=1 && n/10<=9)
cout<<n/10<<endl;//得到最高位
else
splitNum(n/10);
cout<<n%10<<endl;//除最高位之外其余位数以递归过程中的“个位数”形式输出
}
}
//调用函数:
int main()
{
unsigned n;
while(scanf("%d",&n)){
splitNum(n);
}
return 0;
}
测试:

1002

被折叠的 条评论
为什么被折叠?



