程序=数据结构+算法
算法的基本要素:确定性,有穷型,输入输出&可行性!
复杂度度量
时间复杂度
渐进上界:大O记号 渐进下界:大记号 渐进趋势:大记号 常见的时间复杂度类型有,指数型O(2^N) 多项式型O(n^m) 对数型O(logn) 其中O(n),O(1)是多项式型的特殊形式,一般情况下算法的时间复杂度: 对数型 优于 多项式型 优于 指数型。
空间复杂度
空间复杂度类型依然有,指数型O(2^N) 多项式型O(n^m) 对数型O(logn) 常数型O(1) 一般情况下算法的空间复杂度: 对数型 优于 多项式型 优于 指数型。
递归中的算法改进(以Fibonacci序列为例)
二份递归
//代码
int fib(int n)
{
if(n==0||n==1)
return n;
else
return fib(n-1)+fib(n-2);
}
时间复杂度分析: O(2^n)
改进1:线性递归
int fib(int n,int & prev)
{
if(n == 0)
{
prev=0;
return 0;
}
int prevprev=fib(n-1,prev);
return prevprev+prev;
}
空间复杂度:O(n) 时间复杂度:O(n)
改进2:迭代
int fib(int n)
{
int f=0,g=1;
while(0<n--)
{
g=f+g;//prevprev
f=g-f;//prev
}
return g;
}
时间复杂度:O(n) 空间复杂度:O(1)
总结:一个函数的递归调用中,任意子递归是应该独立求解的,如果一个子问题需要另一个子问题的值,或者子问题之间有相互调用,就会引起时间或空间的无谓增加,应尽量利用两个子问题之间的关系,改善递归方法,消除这些问题~
递归展开方法
尾部调用递归
可以使用 迭代
的方法实现,比如上面的fib函数。
迭代定义:指多次计算,每次计算都有新值出现,而且这个新值是由旧值得来的。更加的接近最终结果,迭代一般用循环来做,但没有规定不能用其它方法来做。
其他调用递归
使用栈展开
下一张:数组与线性表