【递归的定义】
①某一个概念是递归的:一个概念自己给自己定义
②某一个函数是递归的:一个函数直接或者间接地调用自己
【递归的意义】
将一个不能或不容易直接求解的“大问题”转化为若干个“小问题”来求解,再将这些“小问题”进一步转化成更小的“小问题”来求解,直至“小问题”可以直接求解。
【递归求解的条件】
①原问题可以通过一个转化过程,改变成为一个新问题,而新问题的求解法与原问题的求解法相同,只是所处理的对象有所不同,这些对象呈现出有规律的递增或递减;
②通过转化使问题的求解得以简化;
③有一个终止转化过程的条件。
例题:
计算:1+2+3+...+100
解答:令S(n)=1+2+3+…+n,
则S(n)= n+S(n-1) (n>1,S(1)=1)
分析:求S(100),可转化为100+S(99),而求S(99)又可转化为99+S(98),如此下去,所处理的对象n分别是100,99,98...,呈现出有规律的递减,而S(1)=1就是 一个终止转化过程的条件。
补充:
递归出口:终止转化过程的条件S(1)=1
递归过程:S(n)= n+S(n-1)
注意:转化过程不是随意的,要保证“大问题”与“小问题”的解法相同
【递归模型】
f(s0)= c0
f(sn)= g(f(sn-1),cn)
注:s0和c0为常数,cn是一个可直接求解的问题,g是一个非递归函数
【递归和迭代】
例题:将十进制数n转化为二进制数。
代码:
#include<stdio.h>
void Dec2Bin1(int n) //递归函数
{
if(n>1)
Dec2Bin1(n/2); //递归过程
printf("%d",n%2); //递归出口
}
void Dec2Bin2(int n) //迭代函数
{
int stack[32],top=-1; //定义一个简易顺序栈
if(n==0){
printf("0");
}
else if(n>0){
do{
stack[++top]=n%2; //n%2入栈
n=n/2; //n被2整除
}while(n!=0);
}
while(top>=0){
printf("%d",stack[top--]); //输出栈中元素
}
}
int main()
{
int n;
printf("请输入需要转换成二进制的十进制数:");
scanf("%d",&n);
printf("递归法求解%d的二进制得:",n);
Dec2Bin1(n);
printf("\n");
printf("迭代法求解%d的二进制得:",n);
Dec2Bin2(n);
printf("\n");
return 0;
}
【递归问题的分类】
①可直接求值,不需要回溯;
②不能直接求值,需要回溯。
分析:这两种递归问题均可转换成迭代求解,前者仅需引入几个变量来保存中间结果(直接转换法),后者需要借助栈来保存中间结果(间接转换法)。
【递归评价】
递归可以解决许多复杂问题;
用递归编程可极大地减少程序代码;
递归函数在执行过程中,需创建递归函数工作栈,从而占用大量内存,当递归调用次数非常大时,有可能耗尽系统的内存资源,使递归调用过程无法返回结果;
递归的执行效率较差。