学习笔录【算法效率分析】

注意:本文摘自《数据结构——从概念到C实现》【王红梅 皮德常 编著】

目录



算法效率分析

度量算法的效率有两种方法

一,事后统计,先实现算法,再输入数据来测量其时间,空间开销。此种方法的缺点至少有

  1. 编写程序实现算法很耗费时间精力
  2. 实验结果依赖于计算机的软硬件等环境因素,有时很容易掩盖算法本身的优劣。

二,事前分析估计,渐进复杂度估算,这是对算法所消耗资源的一种估算方法。



算法的时间复杂度

    同一个算法用不同的程序设计语言实现,或者用不同的编译程序进行编译,或者在不同的计算机上运行,效率均不相同。撇开与计算机软硬件有关的因素,影响算法时间代价的最主要因素是问题规模。问题规模是指输入量的多少,一般来说,它可以从问题的描述中得到。例如,找出100以内的所有素数,问题规模是100;对一个具有n个整数的数组进行排序,问题规模是n。一个显而易见的事实是:几乎任何算法对于规模更大的输入需要运行更长的时间。例如,找出1000内所有的素数比找出100内所有的素数需要更多的时间。所以,运行算法所需要的时间T是问题规模n的函数,记作T(n)。

​    要精确地表示算法的运行时间函数常常是很困难的,即使能够给出,也可能是个相当复杂的函数。为了客观地反映一个算法的执行时间,可以用算法中基本语句的执行次数来度量算法的工作量。基本语句是执行次数与整个算法的执行次数成正比的语句,基本语句对算法运行时间的贡献最大,是算法中最重要的操作。这种衡量效率的方法得出的不是时间量,而是一种增长趋势的度量。换而言之,只考察问题规模充分大时,算法中基本语句的执行次数在渐近意义下的阶,称作算法的渐近时间复杂度,通常使用大O记号表示。

【定义1-1】若存在两个正的常数c和n0,对于任意的n>=n0,都有T(n)<=c * f(n),则称T(n) = O(f(n))(读作“T(n)是Ofn的”,f(n)即与算法的运行时间函数同一数量级的估算函数)

​    此定义表明了函数T(n)与f(n)具有相同的增长趋势,并且T(n)的增长至多趋同于函数f(n)的增长。大O记号用来描述增长率的上限,也就是说,当输入规模为n时,算法耗费的时间的最大值。

​    算法的时间复杂度实际上是一种估算技术,若两个算法中的一个比另一个“稍微快一点”时,并不能基于时间复杂度来判断哪个算法更为优越。但在实际应用中,基于时间复杂度来判断算法的效率被证明是很有效的,尤其在确定算法是否值得实现的时候。常见的时间复杂度如下:
O ( log 2 n ) &lt; O ( n ) &lt; O ( n l o g 2 n ) &lt; O ( n 2 ) &lt; O ( n 3 ) &lt; . . . &lt; O ( 2 n ) &lt; O ( n ! ) O(\log_2n)&lt;O(n)&lt;O(nlog_2n)&lt;O(n^2)&lt;O(n^3)&lt;...&lt;O(2^n)&lt;O(n!)
​    算法的时间复杂度是衡量一个算法优劣的重要标准。一般而言,具有多项式时间复杂度的算法是可以接受的,可使用的算法,而具有指数时间复杂度的算法,仅当问题规模足够小的时候才是可以使用的算法。



算法的空间复杂度

算法在运行过程中所需的存储空间包括:

  1. 输入/输出数据占用的空间
  2. 算法本身占用的空间
  3. 执行算法所需要的辅助空间

    其中,输入/输出数据占用的空间取决于问题,与算法无关;算法本身占用的空间虽然与算法相关,但一般其大小是固定的。所以,算法的空间复杂度是指算法在执行过程中需要的辅助空间数量,也就是除算法本身和输入输出数据所占用的空间外,算法临时开辟出的存储空间。

    如果算法所需的辅助空间相对于问题规模来说是一个常数,我们称此算法为原地(或就地)工作,否则,这个辅助空间数量应该是问题规模的函数,通常记作:
S ( n ) = O ( f ( n ) ) S(n) = O(f(n))
    其中,n为问题规模,分析方法与算法的时间复杂度类似。

猜你喜欢

转载自blog.csdn.net/CreatorGG/article/details/82903887