在函数的执行过程中直接或间接地调用该函数本身,称为函数的递归调用。
递归通常把大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。简言之就是把“大事化小,小事化了。”
例题1:从键盘输入一个无符号整型值,然后按照顺序打印他的每一位。
例:输入12345 输出1 2 3 4 5 。
这道题的思路或方法很多,可以将每一位通过求余和除法算出来,然后从最高为依次打印;也可以通过while/for循环将输入的整数余10,打印后将整数除10,直到整数除10等于0结束循环。
如果用递归来解这道题,其实思想与第二种方法(循环)类似。
#include<stdio.h>
int main()
{
unsigned int n;
scanf("%d",&n);
void loop(int);//函数声明
loop(n);
return 0;
}
void loop(int m)//函数目的是打印,所以不需要返回值
{
if(m>=10)
loop(m/10);
printf("%d ",m%10);
}
如果需要倒序输出的话,只需要在 loop 函数中 printf 放在 if (递归)的前面就好,也方便改动。
例题2:求n!。
#include<stdio.h>
int main()
{
int n;
scanf("%d", &n);
long long s = 0;
long long loop(int);
s = loop(n);
printf("%lld\n", s);
return 0;
}
long long loop(int n)
{
long long j = 1;
if (n == 0)
return 0;
if (n > 1)
{
j = loop(n - 1);
j *= n;
}
return j;
}
例题3:Fibonacci。
#include<stdio.h>
int main()
{
int n;
scanf("%d", &n);
int loop(int);
int sum = loop(n);
printf("%d\n", sum);
return 0;
}
int loop(int n)
{
int f1 = 1, f2 = 1,m=0;
if (n == 1 || n == 2)
return 1;
else
{
m = loop(n - 1) + loop(n - 2);
return m;
}
}
这道题用递归的方法就显得简单暴力。
例题4:不用变量,输出一个字符串长度。
#include<stdio.h>
int length(char *c)
{
if(*c!='\0')
return 1+length(c+1);
else
return 0;
}
int main()
{
char ch[]="hello world.";
printf("%d",length(ch));
return 0;
}
1.*c='h' return 1+length(c+1)
2.*c='e' return 1+length(c+1)
……
12.*c='.' return 1+length(c+1)
13.*c='\0' return 0;
那么开始返回
11.return 1+0
10.return 1+1+0
……
1.return 1+1+1+……+1+0(共十二个1),每循环一次+1,就能算出'\0'之前的字符数量。
例题5:汉诺塔递归求解
#include<stdio.h>
void hanoi(int n,char A,char B,char C)
{
if(n==1)
printf("%c->%c\n",A,C);
else
{
hanoi(n-1,A,C,B);
printf("%c->%c\n",A,C);//到此完成第n个盘子的移动
hanoi(n-1,B,A,C);//继续将中间地的n-1个盘子,借助A,移动到C上
}
/*函数hanoi的理想功能是将A上的所有盘子借助B,最终全部挪到C上,且顺序不变。*/
/*那么记A为起始地,B为中间地,C为目的地*/
/*而A,B,C在函数参量中对应的是1.起始 2.中间 3.结束*/
/*循环一次会将A上n-1个盘子全部挪到B上,将第n个盘子挪到C上*/
}
int main()
{
int n;
scanf("%d",&n);
char A='A',B='B',C='C';
hanoi(n,A,B,C);
return 0;
}
到这里的递归就有点难想了,运用递归虽然有时候思路比较复杂,但它总是可以简化我们的代码。
可以用少量的代码完成复杂的项目。如果能熟练掌握递归,他会成为很好用的工具。