1.将一个函数自身复合多次,便是函数的迭代
用递归还是迭代解决问题,需要视情况而定。
例如:求n!(不考虑溢出)
1.函数递归
//用递归的方式计算n!
#include <stdio.h>
int fac(int n)
{
if (n <= 1)
return 1;
else
return n * fac(n - 1);
}
int main()
{
int n = 0;
scanf("%d", &n);
fac(n);
int ret = fac(n);
printf("ret=%d", ret);
return 0;
}
2.迭代
//用迭代来实现(循环),非递归
#include <stdio.h>
int fac(int n)
{
int i = 0;
int ret = 1;
for (i = 1; i <= n; i++)
{
ret *= i;
}
return ret;
}
int main()
{
int n = 0;
scanf("%d",&n);
fac(n);
int sum = fac(n);
printf("ret=%d", sum);
return 0;
}
例如在求斐波契那数(不考虑溢出)时,更适合用迭代
//求第n个斐波那契数
//斐波那契数列
//1 1 2 3 5 8 13 21 34........
//前两个数的和等于下一个数
//1.递归方式。
#include<stdio.h>
int fib(int n)
{
if (n <= 2)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
//当数目过大时,计算复杂度大大增加
//40
//39 38
//38 37 37 36
//37 36 36 35
//
int main()
{
int n = 0;
scanf("%d", &n);
fib(n);
int ret = fib(n);
printf("%d", ret);
return 0;
}
上述情况,在计算第50个斐波那契数时,需要计算较长时间。
我们不妨设置一个全局变量,来计算第40个斐波那契数时,第三个数的计算次数。
#include<stdio.h>
int count = 0;
int fib(int n)
{
if (n == 3)
count++;
if (n <= 2)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
//当数目过大时,计算复杂度大大增加
//40
//39 38
//38 37 37 36
//37 36 36 35
//
int main()
{
int n = 0;
scanf("%d", &n);
fib(n);
int ret = fib(n);
printf("%d\n", ret);
printf("%d\n", count);
return 0;
}
结果可以看到
当求第40个数时,第三个斐波那契数已经被重复计算了78176338次,可想而知其复杂程度过大。
计算次数以指数形式增长,在这种情况下反而更适合用迭代。
#include<stdio.h>
int fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
int i = 0;
while (n >= 3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
fib(n);
int ret = fib(n);
printf("%d", ret);
return 0;
}
这种计算结果方便高效。也可以使用for循环替代while循环。
//适合用迭代(不考虑内存溢出)
#include<stdio.h>
int fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
int i = 0;
/*while (n >= 3)
{
c = a + b;
a = b;
b = c;
n--;
}*/
for (i = 3; i <= n; i++)
{
c = a + b;
a = b;
b = c;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
fib(n);
int ret = fib(n);
printf("%d", ret);
return 0;
}