这次文章比较短但是很精练易懂
我们这次的递归主要以斐波那契数为例
1自定义一个函数使他逆序输出
这个代码比较简单基础
思路 就是让这个数一直除10直到小于10然后打印
核心思想化大事为小事
要打印一个数的逆序得 要知道它的 最后一位+除去最后一位的最后一位
依次论推
看代码
#include<stdio.h>
void Reverse(int n)
{
printf("%d ",n%10);
if(n>9)Reverse(n/10);
}
int main()
{
int n;
scanf("%d",&n);
Reverse(n);
return 0;
}
通过这个我们得总结出规律
1函数递归要有限制条件
2函数递归每一次递归都接近这个条件
接着我们看第二个例子
求解斐波那契数列问题,求第n个数
我们仍然使用递归来完成
那么什么事斐波那契数
1 1 2 3 5 8 13 21 34 55``````
前两个数都是1 但是从第三个数开始该数等于前1个和前两个数之和
那么递归思路如何呢
要得到第n个数
就要得到第 n-1和n-2个数字
要得到第n-1个数字
又要得到n-3和n-2``````
诸如此类依次进行
当然这个图这是一部分,他会一直到 第一个数和第二个数才会结束
看看代码实现
int Fiber(int n)
{
if(n<3)
return 1;
else
return Fiber(n-1)+Fiber(n-2);
}
int main()
{
int n;
scanf("%d",&n);
int i=Fiber(n);
printf("%d",i);
return 0;
}
当然可以给大家看看不足之处
1首先当到50时系统算了好久都算不出来
2当数字太大时可能还超过其表达的范围
优化方案
如果还想使用递归算法,最好使用一个数组记录每一个波菲那契数
看代码
long long arr[1000] = { 0 };
long long Fiber(int n)
{
if (arr[n])
return arr[n];
if (n < 3)
return 1;
else
arr[n] = Fiber(n - 1) + Fiber(n - 2);
return arr[n];
}
int main()
{
while (1)
{
int n;
scanf("%d", &n);
long long i = Fiber(n);
printf("%lld\n", i);
}
return 0;
}
看运行情况
此时连100也能够轻松求解
当然我们大可不必使用递归来解决问题,完全可以使用循环来解决
看代码
long long Fiber(int n)
{
long long arr[1000] = { 0 ,1,1};
for (int i = 3; i <= n; i++)
{
arr[i] = arr[i - 1] + arr[i - 2];
}
return arr[n];
}
这样解决问题同样很快
此时我们还能优化吗
答案是肯定的
由于我们要的数字只取决于前两个数
所以我们可以不用一个数组,只用两个局部变量即可
看代码
long long Fiber(int n)
{
unsigned long long pre = 1;
unsigned long long cur = 1;
while (n > 2)
{
unsigned long long temp = cur;
cur += pre;
pre = temp;
n--;
}
return cur;
}
这已经是我们的第三次优化了
时间复杂度已经变为O(n)
空间复杂度变为O(1)
结果与上面是一样的具体还是要看优化的思路
今天的内容虽少但是很精炼
希望大家能理解