前言
算法分析主要包含时间代价和空间代价两方面。
这部分内容个人认为是相当重要的,在面试环节经常会问到一个算法的时间复杂度,因此需要熟练掌握。
时间代价分析
算法的时间代价是指算法执行时所花费的CPU时间量,它是算法中涉及的存、取、转移、加、减等各种基本运算的执行时间之和,与参加运算的数据量有关,很难事先计算得到。
算法的时间效率是指算法的执行时间随问题规模的增长而增长的趋势,通常采用时间复杂度(Time Complexity)来度量。当问题的规模以某种单位从1增大到n时,解决这个问题的算法在执行时所耗费的时间也以某种单位从1增大到T(n),则称此算法的时间复杂度为T(n)。当n增大时,T(n)也随之增大。
采用算法渐进分析中的大O表示法作为算法时间复杂度的渐进度量值。大O表示法是指,当且仅当存在正整数c和n0,使得T(n)≤c×f(n)对所有的n≥n0成立时,称该算法的时间增长率与f(n)的增长率相同,记为T(n)=O(f(n))。
若算法的执行时间是常数级,不依赖于数据量n的大小,则时间复杂度为O(1);若算法的执行时间是n的线性关系,则时间复杂度为O(n);同理,对数级、平方级、立方级、指数级的时间复杂度分别为O(log2n)、O(n2)、O(n3)、O(2^n)。
这些函数按数量级递增排列具有下列关系:O(1)<O(n)<O(log2n)<O(n×log2n)<O(n2)<O(n3)<O(2^n)。
时间复杂度O(f(n))随数据量n变化情况的比较如下表所示:
如何估算算法的时间复杂度?一个算法通常由一个控制结构和若干基本操作组成,则:
由于算法的时间复杂度表示算法执行时间的增长率而非绝对时间,因此可以忽略一些次要因素,算法的执行时间绝大部分花在循环和递归上。设基本操作的执行时间是常量级O(1),则算法的执行时间是基本操作执行次数之和,以此作为估算算法时间复杂度的依据,可表示算法本身的时间效率。
每个算法渐进时间复杂度中的f(n),可由统计程序步数得到,与程序结构有关。循环语句的时间代价一般可用以下三条原则进行分析:
- ① 一个循环的时间代价=循环次数×每次执行的简单语句数目
- ② 多个并列循环的时间代价=每个循环的时间代价总和
- ③ 多层嵌套循环的时间代价=每层循环的时间代价之积
时间复杂度分析的案例
结合上面的理论看完案例后应该很容易就掌握了时间复杂度计算方法
-
① 一条简单语句的时间复杂度为O(1)。例如:
-
② 执行n次的循环语句,时间复杂度为O(n)。例如:
-
③ 时间复杂度为O(log 2n)的循环语句如下:
其中,i取值为1、2、4、8,循环执行1+log2n次,故循环语句的时间复杂度为O(log 2^n)。 -
④ 时间复杂度为O(n^2)的二重循环如下:
外层循环执行n次,每执行一次外层循环时,内层循环执行n次。所以,二重循环中的循环体语句执行n×n次,时间复杂度为O(n^2)。如果
则外层循环执行n次,每执行一次外层循环时,内层循环执行i次。此时,二重循环的执行次数为:
,时间复杂度仍为O(n^2)。 -
⑤ 时间复杂度为O(n×log 2^n)的二重循环如下:
外层循环执行1+log2n次,内层循环执行次数恒为n,总循环次数为n×(1+log2^n),时间复杂度为
O(n×log2^n)。 -
⑥ 时间复杂度为O(n)的二重循环如下:
外层循环执行1+log 2^n次,i取值为1,2,4,…,内层循环执行i次,i随着外层循环的增加而成倍递增。总循环次数为:
,时间复杂度为O(n)。
空间复杂度分析
算法的空间代价是指算法执行时所占用的存储空间量。
执行一个算法所需要的存储空间包括三部分:输入数据占用的存储空间、程序指令占用的存储空间、辅助变量占用的存储空间。其中,输入数据和程序指令所占用的存储空间与算法无关,因此,辅助变量占用的存储空间就成为度量算法空间代价的依据。
当问题的规模以某种单位从1增大到n时,解决这个问题的算法在执行时所占用的存储空间也以某种单位从1增大到S(n),则称此算法的空间复杂度(Space Complexity)为S(n)。当n增大时,S(n)也随之增大。空间复杂度用大O表示法记为S(n)=O(f(n)),表示该算法的空间增长率与f(n)的增长率相同。
例如,交换两个变量i、j算法,除了程序指令和i、j本身占用的存储空间之外,为了实现交换操作,还必须声明一个临时变量temp,这个temp变量所占用的1个存储单元就是交换变量算法的空间复杂度O(1)。
标签:分析,复杂度,算法,循环,时间,执行,存储空间 来源: https://blog.csdn.net/Android_xue/article/details/101067819
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。