递归
一、内容总结
如果一个复杂的过程中可以看做一个子过程层层套用的形式,就可以用递归。 递归是调用自身的过程,即把复杂问题转化成新的较简单的问题,新的问题又可以转化成解决方法相同的更简单的新问题,直到终止。难点就在于找到开始的点、递归的条件和终结条件。思路形成的过程是由复杂向简单靠拢。找到最简单的条件就是终结条件,递归过程中所有的步骤都是向简单运算进行。
二、干什么用的(应用举例)
先举个例子
此题是上学期课程设计的题目之一,猴子吃桃子,借由此题说明递归含义。递归的过程是倒着想,实际是正着算。这与递推(通常for)正好相反。
法一(递推)
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
ans=(ans+1)*2;
}
cout<<ans<<endl;
return 0;
}
法二(递归函数)
#include<bits/stdc++.h>
using namespace std;
int n;
int func(int n)
{
if(n==1)
return 1;
else
{
return (func(n-1)+1)*2;
}
}
int main()
{
cin>>n;
cout<<func(n)<<endl;
return 0;
}
常态思路都是由已知到未知(即递推);而递归则是由未知到已知,在运算的过程中化到最简问题之后再进行递推来求复杂解。递归就像分析的解题过程,从结果入手倒着推条件,再由已知开始写证明过程。
再看 斐波那契数列题也可用递归函数
(如:求解fib第n项的值)
法一(递归)
int fib(int n)
{
if(n==1||n==2)
return 1;
else
return (fib(n-1)+fib(n-2));
}
int main()
{
cin>>n;
cout<<fib(n)<<endl;
return 0;
}
法二(递推)
int main()
{
int a=b=1,c,n;
cin>>n;
for(int i=3;i<=n;i++)
{
c=b;
b=a+b;
a=b;
}
cout<<n<<endl;
}
注:经前人验证在oj上用递归算某些题会超时
3.二分法递归求解过程不复杂
int bb(int low ,int high)
{
if(low>high)
return -1;
int mid=(low+high)/2;
if(n==a[mid])
return mid;
else if (n<a[mid])
return bb(low,mid-1);
else
return bb(mid+1,high);
}
4 .二的幂次方 关键在于由大到小找二的幂次方,中间用加号
void pp(int mm)
{
int k;
for(k=15;k>=0;k--)
{
if(a[k]<=mm) break;
}
if(k==0)cout<<"2(0)";
else if(k==1)cout<<"2";
else if(k==2)cout<<"2(2)";
else
{
cout<<"2(";
pp(k);
cout<<")";
}
if(mm-a[k])
{
cout<<"+";
pp(mm-a[k]);
}
}
三、这段时间的感悟
这是一篇积极性不高的感悟
第一周我还是比较认真地听课自己在纸上写写画画,想着到第二周再交题,然而第二周个人积极性明显下降,以程序设计B迟到为开端,以知识太难了、担心学不会、跟不上趟、专业作业多、自己的必修课知识多为借口,开始逃避,又开始犹豫要不要接着蹭课学习,不知道自己到底为了什么,更不知道自己想要什么…虽然很喜欢ac的感觉,但是出一个ac很不容易。现在对递归以及现在学的贪心有一种恐惧感,对自己的现状很迷…
在喝了心灵鸡汤之后要重新写了
老师说可以试一试,不要低估了自己,只要肯花时间钻研,还有啥是弄不明白的。那么,现在就这里和自己约定个时间吧,从这篇博客开始到返校,在这一段时间里用心学、投入精力和时间去学,到返校的时候看看自己学会了多少,有多少长进,总得对得起带我c++入门的人。