算法时间复杂度

xiaoxiao2021-02-28  9

算法时间复杂度

作为一个正在学习的iOS渣渣,算法、数据结构、操作系统、网络相关已经基础知识已经忘记差不多了。最近正在总结排序算法,哎我滴妈,时间复杂度也不会估算,作为程序员这就有点可悲了,接下来就一点点点的重新再学一遍吧。先了解一下时间复杂度哇。

算法时间复杂度定义

在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的时间复杂度,也就是算法的时间度量,记作:T(n) = O(f(n)),它表示随着问题规模n的增大而增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。其中f(n)是问题规模n的某个函数。

这样用大写O()来体现算法时间复杂度的记法,称之为大O记法。

一般情况下,随着n的增大,T(n)增长最慢的算法为最优算法。

时间复杂度计算方法:推导大O阶方法

推导大O阶:

用常数1取代运行时间中的所有加法常数。在修改后的运行次数函数中,只保留最高阶项。如果最高阶项存在且不是1,则去除与这个项相乘的常数。

得到的结果就是大O阶。通过这个步骤,得到算法的运行次数的表达式后,很快就会得到算法时间复杂度。

伙伴们注意啦,虽然根据大O阶得算法时间复杂度很容易,但是得到算法的运行次数的表达式还是需要一点数学功底的。

常见的时间复杂度如O(1)、O(n)、O(n^2)、O(logn),通常叫分别叫他们常数阶、线性阶、平方阶、对数阶,那么接下来看几个例子。

常数阶

int sum = 0, n = 100; //执行一次 sum = (1 + n)/2; //执行一次

上述代码运行次数函数是f(n)=2,根据我们推导大O阶的方法,第一步就是把常数项2改为1,第二部将保留最高阶项发现没有最高阶,所以上述代码时间复杂度为O(1)。

线性阶

int sum = 0, n = 100; for(int i = 0; i < n; i ++) { sum = (1 + n)/2; }

上述代码的循环时间复杂度为O(n),循环体代码需要执行n次。

对数阶

int count = 1; while(count < n){ count = count * 2; }

上述代码时间复杂度为O(logn)。while的终止条件为count < n,while的终止条件也就是多少个2相乘大于n,则会退出循环。由2^x = n得到x=log2^n,根据大O阶第三条“去除与这个项相乘的常数”,所以上述循环时间复杂度为logn。

平方阶

int sum = 0, n = 100; for(int i = 0; i < n; i ++) { for(int j = 0; j < n; j ++) sum = j + i; }

上述代码时间复杂度为O(n^2)。那么我们考虑将循环次数改变一下,比如将第二个循环中j从n开始,那么时间复杂度是怎么变化的呢?代码如下:

int sum = 0, n = 100; for(int i = 0; i < n; i ++) { for(int j = n; j < n; j ++) sum = j + i; }

sum计算的次数为:n+(n- 1)+(n- 2)+…+1=n(n+1)/2= n^2/2 + n/2

用推导大O阶的方法,第一条,没有加法常数不用考虑,第二条保留最高阶,保留n^2/2,第三条,去除最高项常数,最后得到时间复杂度为O(n^2),与未修改之前的时间复杂度是相同的。

常见的时间复杂度

常见的时间复杂度所耗时间的大小排列如下:

0(1)<O(logn)<O(n)<O(nlogn)<0(n2 ) <0(n3 ) <0(2")<O(n!)<O(nn)

最坏的时间复杂度

最坏的情况运行时间是一种保证,那就是运行时间不会再坏了,通常,除非是特别的指定,我们提到的运行时间都是最坏的情况的运行时间。

平均时间复杂度

平均运行时间是所有情况中最有意义的,因为它是期望的运行时间。也就是说,我们运行一段代码时,是希望看到平均运行时间的,可现实中,平均时间复杂度很难通过分析得到,平均时间复杂度需要运行一定数量的实验数据估算出来的。

时间复杂度介绍到这就结束了。后续学习继续更新。 此次学习参考了程杰的《大话数据结构》。

转载请注明原文地址: https://www.6miu.com/read-1250196.html

最新回复(0)