一、递归函数总述
1、递归函数:在函数定义中出现直接或间接对自身的调用的函数。
2、作用:解决多次重复计算,通常把问题由大化小,小问题一般为已知或易得到的数据。
3、优点:大大减少了程序的代码量,用有限的语句来定义对象的无限集合。
4、运用心得:要勤加练习,形成一个自己的思考方式,从而找对其中的递归关系。
二、递归题型总结
1、首先以求n的阶乘为例
#include <bits/stdc++.h>
using namespace std;
int jc(int n);
int main()
{
int n;
cin>>n;
cout<<jc(n)<<endl;
return 0;
}
int jc(int n)
{
if(n==0||n==1) return 1;
return n*jc(n-1);//此处体现了n的阶乘就等于n乘以n-1的阶乘,直到递归到1
}
2、用递归方法求最大公约数问题
(同求n的阶乘类型一致,只需找出其中的递归关系即可,在此只说明具体递归函数)
int gys(int m,int n)//求m,n的最大公约数
{
return n==0? m:gys(n,m%n);//当余数为0时,最大公约数就是其除数,在此用三元运算符体现,效果等同if语句
}
3、数据查找问题(二分查找递归)
#include<bits/stdc++.h>
using namespace std;
int a[1001];
void search(int x,int m,int n);//从第m个数据到第n个数据中寻找x
int main()
{
int i,x,m,n;
cin>>x>>m>>n;
for(i=m;i<=n;i++)
cin>>a[i];//数据大小已经按照由大到小排序输入,如果乱序先要排序
search(x,m,n);
return 0;
}
void search(int x,int m,int n)
{
int mid;
if(m<=n)//这里需要m<=n
{
mid=(m+n)/2;//求出中间数的位置
if(x==a[mid]) cout<<"YES"<<endl;
else
{
if(x<a[mid]) search(x,mid+1,n);//判断在前半段还是后半段以确认接下来在哪段查找
else search(x,m,mid-1);
}
}
else cout<<"NO"<<endl;
}
4、半数集问题(记忆化搜索)
#include<bits/stdc++.h>
using namespace std;
int r[1001];//定义一个数组r,用于存放已经计算出的该数集内元素个数
void bsj(int m)
{
int i;
if(r[m]!=-1) return r[m];//已经被赋值的可直接调用
r[m]=1;//m本身也是一种情况,故赋值1
for(i=1;i<=m/2;i++)
{
bsj(i);
r[m]+=r[i];//将m的所有分集求和得r[m]并记录数据
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
r[i]=-1;//r数组初始化
bsj(n);
cout<<r[n];//利用记忆数据求解
return 0;
}
5、全排列问题
void qpl(int list[],int k,int m)
{
if(k==m)//构成一次全排列,输出结果
{
for(int i=0;i<=m;i++)
cout<<list[i]<<" ";
cout<<endl;
}
else
for(int j=k;j<=m;j++)
{
swap(list[k],list[j]);//固定位置k,j从k到m不断赋值与固定位置替换
qpl(list,k+1,m);//固定下一个位置,重复操作,直到k=m
swap(list[k],list[j]);//完成一次排序后换回
}
}