在看<span style="font-family: Simsun; font-size: 18px;">Data Structures and Algorithm Analysis in C (Second Edition)关于递归的四条基本法则:</span>
1-基准情形:必须有递归出口
2-不断推进:不断的靠近递归出口
3-设计法则:所有的递归法则都是能够运行的
4-合成效益法则(compound interest rule):不能在递归调用做重复的事情(最重要的法则),不然效率低的不能看,比如斐波那契递归 是指数级的时间复杂度;
例子:求Fib(5)的值,如图,可以看到 2次Fib(3) 3次Fib(2) 5次Fib(1) 大量的重复调用函数计算,开销还蛮大的,所以要避免这样的递归的设计;
解决方法:
1-动态规划(置底向上):未来的每一步 都利用 之前计算得到的值 来计算,即是迭代。可以在O(N)解决;
代码:
#include<stdio.h>
int Fib(int n)
{
int f , f1 ,f2 , i ;
if ( n < 2 )
return n ;
else
{
f1 = f2 = 1 ; //Fib(1) Fib(2) 初始值
for(i = 2 ; i < n ; i++ ) //从第三数开始
{
f = f1 + f2 ; //迭代的开始
f1 = f2 ;
f2 =f ;
}
}
return f;
}
int main()
{ int i ;
i = Fib(5);
printf("Fib(5):%d \n",i);
return 1 ;
}
结果:
Fib(5):5
Process returned 1 (0x1) execution time : 0.033 s
Press any key to continue.
2-动态规划置顶向下
代码:
#include<stdio.h>
int fib_array[50] = {0};
int Mem_fib(int n)
{
int t ;
if ( fib_array[n] != 0 )
return fib_array[n];
if ( n == 0 )
t = 0 ;
if ( n == 1 )
t = 1 ;
if ( n > 1 )
{
t = Mem_fib(n-1) + Mem_fib(n-2) ;
}
return fib_array[n] = t;
}
int main()
{ int i ;
i = Mem_fib(5);
printf("Fib(5):%d \n",i);
return 1 ;
}
结果:
Fib(5):5
Process returned 1 (0x1) execution time : 0.053 s
Press any key to continue.
记住法则!
利用法则,写出高效的代码!