算法的时间复杂度分析

评估一个算法的效率,不能使用什么实时的计量单位,比如秒啊,微妙啊啥的,最好用逻辑单位,他能表示数据规模N与时间t的这样一种关系,然后分析这种关系的一种增长曲线

一般一个算法我们都会用函数来表示,一般我们取函数项里面增长最快的一项。因为我们考虑算法的时候,主要就是考虑问题规模特别大的时候,小数据规模,你的算法是什么时间复杂度,影响都没有多大,这也是我们经常分析问题的一种思维,考虑问题,我们一般要考虑最坏的情况。

函数增长最快一项与问题规模特别大这个其实相互独立,每一个函数问题规模都可以增大,也都有增长速率,但是我们主要去研究函数的增长速率。

比如一个函数f(x)=n^2+100*n+1+2^n

上面有一种很明显的时间复杂度关系:2^n>n^2>100*n>1

也就是说当数据足够大的时候,我们主要去关注函数增速最快的一项,在分析n的取值的时候,也要保证最快的一项始终是增长最快的一项。

下面用一个图像来看与幂函数与指数函的增长情况:

绿色代表2^n(指数在不停改变) 蓝色代表n^2(幂函数),在最开始数据规模比较小的是时候,很明显n^2>2^n,但是我们去看一下数据规模超过了一定的值之后,函数情况是怎么发生改变的。

很明显2^n远远大于n^2的数值增长。

说一下时间复杂度是通过大O来表示的,

定义:存在一个正数c与N,对于所有的n>=N,也即是一个问题规模的临界点,f(n)<=cg(n),此时f(n)=O(g(n)),这个g(n)函数就代表了时间复杂度(我们可以用常见的算法时间复杂度去分析)

 

现在我们来重点讲解一下上面这句话:

假设一个函数的运行次数的函数是f(n)=2*n^2+3*n+1,那么这个时候,我们把g(n)考虑成它增长最快的一项f(n)=O(n^2);

此时我们来分析一下N与c的值:

也就是不同的c取值对应的g(n)函数与f(n)的交点(交点也不一样),然后取出来的N是不一样的。

假设N取1,2,3,4..我们来分析一下图像:

 

上面就是y=6*x^2(蓝色)与y=2*x^2+3*x+1(绿色)的对比图像,很明显可以看见,他们交互的n=1,当n>1,g(n)完全大于f(n),所以,我们就可以列出c与N取值对照表

N   1      2

c   >=6    >=3.75  .......

上面好像就是通过大N来决定C的取值,他们必定有一个相同的值进行交会,这个定理好像就是一个验证。

也即是n>=N,然后g(n)完全大于f(n)的条件是c必须大于等于某一个数,然后两个函数恰好交互在某一个数上面。

再来分析一下原函数2*n^2+3*n+1<=cn^2   ===>   2+3/n+1/n^2<=c  =====>

根据n来推算出c,根据原函数取值就可以算出来。,因为他们必定有一个交点。

那么我们如何选择合适的c与N呢?,我们最好看哪一个N可以让f增长最快的某一项始终保持最大,上面原函数最大项是2*n^2与3^n,如果N取1,那么不等式2*n^2>3*n就不满足,那么如果N=2,2*n^2>3*n .因为毕竟c是通过N进行推算出来的。

其实上面就是想说,对于一个给定函数f,有无穷多的g与之对应,原函数不仅仅是O(n^2)的g函数,还可以是n^3,n^4,也就是只要满足fn<=cg(n),这样的条件都可以,为了避免这种情况,我们一般选择较小的函数g来表示算法时间复杂度,比如2次幂就差不多了。

下面来说一下大O表示法的一些性质:

性质1传递性

f(n)=O(g(n))  g(n)=O(h(n)))   ===>  f(n)=O(h(n)),而g(n)的时间复杂度就等于它本身的时间复杂度

原函数的时间复杂度等于g(n)的时间复杂度

看一下上面函数的图像:

上面我们就是截取了部分图像进行分析,很明显,N1与N2,然后我们选择图那一个点,也就是N2,g(n)函数与他的g(n)函数的一个交会点,那么之后,不管n取什么值,他都大于等于f(n)(红色  )

上面这种关系换一种方式来表示:

f(n)=2n^2+3n+1

g(n)=n^2

h(n)=n^2

现在我们假设,上面论证了c>=6 N=1,也就是说c1我就取6  ==> f(n)<=c1g(n),此时g(n)是fn的一个时间复杂度。c1=6 N1=1

好,这里我们又假设g(n)<=c2h(n)  那么c1=6,我们只要c2>6就可以大于g(n)的函数了并且大于N=1时的f(n)函数,我们比如c2取7, h(n)=n^2,那么N2只能取0,(这里的意思就会使6*n^2 == 7*n^2,这里n只能取0)只要大于N>0,c2h(n)就始终大于g(n),要也就是g(n)<=7h(n),此时h(n)就是它的算法时间复杂度。

ok,那么我们现在知道了几个条件

c1=6 N1=1   c2=7 N2=0

因为c1g(n)<=c2h(n)  ==> c1g(n)<=c1*c2h(n)

这个时候,我们把c1*c2=c,那么也就是说c1g(n)<=ch(n)  ===>  f(n)<=ch(n)

所以h(n)也就是f(n)的算法时间复杂度。

 

下面我们再来说一个性质2:如果f(n)=O(h(n))并且g(n)=O(h(n)),那么f(n)+g(n)=O(h(n))

当f(n)+g(n),它的最高增量也是最高次幂,他们表示的函数必定远远小于ch(n),其中的c=c1+c2

 

下面再来说一下性质3:

函数a*n^k=O(n^k)

要满足不等式a*n^k<=c*n^k  需要令c>=a

 

再来说一下性质4:对任意正数j,函数n^k=O(n^k+j)

n^k<=n^k+j  当c=1   ==》  N=1,这个关系就满足了,当N>1,g(n)函数就远远大于f(n)

 

 性质5,如果f(n)=cg(n),那么f(n)=O(g(n));

这个时候,把N换成刚好相等那个N就可以了、

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页