前尘----时间复杂度和空间复杂度计算

算法:算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或者多个操作。

算法的五个特性: 

  • 输入输出:算法具有零个或多个输入,算法至少有一个或者多个输出。输出的形式可以是打印也可以是返回一个或者多个值。
  • 有穷性:指算法在执行有限步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成。
  • 确定性:算法的每一步骤都具有确定的含义,不会出现二义性,算法在一定条件下,只有一条执行路径,相同的输入只能有唯一的输出结果。算法的每个步骤被精确定义而无歧义。
  • 可行性:算法的每一步都必须是可行的,也就是说,每一步都能够通过执行有限次数完成。可行性以为着算法可以转换为程序上机运行,并得到正确的结果

算法的设计要求: 

  • 正确性:算法的正确性是指算法至少应该具有输入、输出和加工处理无歧义性、能正确反映问题的需求、能够得到问题的正确答案。算法正确性从低到高有4层含义:(1)算法程序没有语法错误;(2)算法程序对于合法的输入数据能够产生满足要求的输出结果;(3)算法程序对于非法的输入数据能够得出满足规格说明的结果;(4)算法程序对于静心选择的,甚至刁难的测试数据都有满足要求的输出结果。优良的算法设计通常至少要满足到第三层。
  • 可读性:算法设计的另一目的是为了便于阅读、理解和交流。
  • 健壮性:当输入数据不合法时,算法也能做出相关处理,而不是产生莫名其妙的结果
  • 时间效率和存储量低:设计算法应尽量满足时间效率高和存储量低的需求

算法效率的度量

  1.事后统计方法:这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同的算法编制的程序运行时间进行比较,从而确定算法效率的高低。

  2.事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算。

  一个用高级语言编写的程序,在计算机上运行时所消耗的时间取决于以下因素:

  (1)算法采用的策略、方法;

  (2)编译产生的代码质量;

  (3)问题的输入规模;

  (4)机器执行指令的速度

  测定运行时间最可靠的方法就是计算对运行时间有消耗的基本操作的执行次数,运行时间与这个计数成正比。在分心程序的运行时间时,最重要的是把程序看成是独立于程序设计语言的算法或一系列步骤。

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

  像上面这段代码,其输入规模为n,那么时间消耗总量(消耗时间的基本操作的次数,一次基本操作的时间消耗,假设它为O(1),我们把它记为f(n),忽略循环头的时间消耗。假设求和这样的基本操作时间消耗为1,那么在上述算法中,这个求和过程被重复执行了n次,那么f(n) = n;

  在分析一个算法的运行时间时,重要的是把基本操作的数量与输入规模关联起来,即基本操作的数量必须表示成输入规模的函数。

函数的渐进增长

  函数的渐进增长:给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的n>N,f(n)总是比g(n)大,那么,我们说f(n)的增长渐进快于g(n)。

  判断一个算法的效率时,函数中的常数和其它次要项常常可以忽略,而更应该关注主项(最高阶项)的阶数。如果可以对比几个算法的关键执行次数函数的渐进增长性,基本就可以分析:某个算法,随着n(输入规模)增大,它会越来越优于另一算法,或者越来越差于另一算法。这就是事前估算方法的理论依据,通过时间算法复杂度来估算算法的时间效率。

算法的时间复杂度

  算法时间复杂度:在进行算法分析时,语句总的执行次数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(1)俗称为常数阶,O(n)俗称线性阶,O(n^2)俗称为平方阶。

推导大O阶方法

  1.用常数1取代运行时间中的所有加法常数

  2.在修改后的运行次数函数中,只保留最高阶项。

  3.如果最高阶项存在且不是1,则去除与这个项相乘的常数,得到的结果就是大O阶。

注:顺序结构的时间复杂度是O(1),当然前提是这些都是基本操作,例如赋值啊,比较啊等等。

  单纯的分支结构(不包含在循环结构里)的时间复杂度也是O(1),前提也是分支的操作都是基本操作。

  循环结构的时间复杂度就不一定了,单纯的循环结构就向上面举的求和的例子,其时间复杂度就是O(n)。

  要确定某个算法的阶次,我们常常需要确定某个特定语句集运行的次数。因此,我们要分析算法的复杂度,关键就是要分析循环结构的运行情况。

对数阶

int count = 1;
while(count < n)
{
    count = count*2;
    ...    //时间复杂度为O(1)的程序步骤序列
}

那么这个算法的时间复杂度是多少呢?显然对这个算法来说其输入规模的最大值是n,count是每一轮循环的输入规模,那么当count渐进增长超过n的时候基本操作语句总共执行了多少次呢?
观察发现,count每一次循环都是上一次的两倍。
那么假设执行的次数为x,输入规模为变量n,可以得出x和n的关系是:
                    2^x = n;
 计算算法时间复杂度,我们要求的是执行总次数关于输入问题规模的函数,因此,对上述等式进行变化得:
                  x = log2(n)
    即f(x) = log2(n);
    接下来推导大O记法。
    上述算法的时间复杂度为 O(log(n))。
    在这里一般会省略log2n中的2,这是因为有换底公式的存在,使得底数具体是多少不需要去关心。

平方阶

  平方阶一般见于简单的嵌套for循环

  例如:

for(int i = 0; i < n: ++i)
{
    for(int j =0; j < n:++j)
    {
        /*时间复杂度为O(1)的程序步骤序列*/
    }
}对于外次for循环的每一次执行,内层for循环都要执行n此,问题的输入规模为n,那么执行的总次数就是n^2,即f(n) = n^2按照大O阶的记法,这个算法的时间复杂度为O(n^2)如果外层的循环变量改为了m。那么外层的输入规模为m,内层的输入规模是n,对外层的每一次执行,内层循环都要执行n此,所以总次数就是n*m因此其时间复杂度为O(m*n)因此,循环的时间复杂度等于循环体的复杂度乘以该循环运行的次数。
for(int i =0; i<n; ++i)
{
    for( j = i; j< n; ++j)
    {
        /*算法时间复杂度为O(1)的程序步骤序列*/
    }
}

对这个算法的时间复杂度进行计算,
当i = 0 时,内层循环执行了n次,当i= 1时,内层循环执行了n-1次,当i = 2时内层循循环执行了n-2次……当i等于n-1次时,内层循环执行了1次,那么总的执行次数就是
    f(n) = n+ (n-1) + (n-2) + (n-3) +... +1 = n(n+1)/2 = n^2/2 + n/2
那么它的时间复杂度就是O(n^2)

  时间复杂度,难点在于对数列的进行的相关运算,所以计算时间复杂度,要强化基础数学能力,尤其是数列方面的知识。

包含方法调用的时间复杂度计算

  简单来说,你把函数调用当做宏定义在原地展开,然后按照上面的示例计算即可。也可以利用大O的加法或乘法法则计算,其实都一样

  大O的加法法则:f1(n) + f2(n) = O(max(f1(n),f2(n)); f1、f2是为两个关于属于规模和基本运算执行次数的函数,加法运算适用于顺序结构、if结构、switch结构

  大O的乘法法则:f1(n)*f2(n) = O(f1(n) * f2(n))  适用于嵌套的循环,例如上述例子的嵌套for,外层的时间复杂度为O(n),即运算次数和属于规模的函数是f1(n) = n;内层循环的时间复杂度也是O(n),其运算次数和输入规模的函数是f2(n) = n,那么整个嵌套for循环的时间复杂度就是O(n*n)。

  简单布尔计算或算数运算以及简单I/O(内存I/O)的时间复杂度是O(1),这个也是大O表示法的单位时间。至于O(1)具体是多长时间,定义这个量值是没有意义的,因为,计算时间复杂度,我们只是希望从理论角度出发,大致的估量它可能消耗的时间,程序的具体运行时间消耗还有赖于具体硬件平台的处理效率。

最坏情况与平均情况

  最坏情况运行时间是一种保证那就是运行时间将不会再坏了。在应用中这是一种最重要的需求。

  平均运行时间是期望算法的运行时间。

  对算法的分析,一种方法是计算所有情况的平均值,这种时间复杂度的计算方法称为平均时间复杂度。另一种方法是计算最坏情况下的时间复杂度。这种方法称为最坏平均时间复杂度、

算法的空间复杂度

  算法的空间复杂度:通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记作:S(n) = O(f(n)),其中n为问题的规模,f(n)为语句关于n所占存储空间的函数。一般情况下,一个程序在机器上执行时,除了需要存储程序本身的指令、常数、变量和输入外,还需要存储对数据操作的存储单元。若输入数据所占空间只取决于问题本身,和算法无关,这样只需要分析该算法在实现时所需的辅助单元即可。若算法执行时所需的辅助空间相对于输入数据量而言是个常数,则称此算法为原地工作,空间复杂度为O(1)。通常,使用“时间复杂度”来指运行时间的需求,使用“空间复杂度”指空间需求。一般说到复杂度,其实都是指“时间复杂度”。

原文地址:https://www.cnblogs.com/ToBeExpert/p/9755905.html

时间: 2024-11-10 11:42:36

前尘----时间复杂度和空间复杂度计算的相关文章

时间复杂度和空间复杂度计算

时间复杂度: 首先要说的是,时间复杂度的计算并不是计算程序具体运行的时间,而是算法执行语句的次数. 当我们面前有多个算法时,我们可以通过计算时间复杂度,判断出哪一个算法在具体执行时花费时间最多和最少. 常见的时间复杂度有: 常数阶O(1), 对数阶O(log2 n), 线性阶O(n), 线性对数阶O(n log2 n), 平方阶O(n^2), 立方阶O(n^3) k次方阶O(n^K), 指数阶O(2^n). 随着n的不断增大,时间复杂度不断增大,算法花费时间越多. 计算方法 ①选取相对增长最高的

【405】算法时间复杂度和空间复杂度的计算

参考:算法时间复杂度和空间复杂度的计算 时间复杂度计算 去掉运行时间中的所有加法常数.(例如 n2+n+1,直接变为 n2+n) 只保留最高项.(n2+n 变成 n2) 如果最高项存在但是系数不是1,去掉系数.(n2 系数为 1) 原文地址:https://www.cnblogs.com/alex-bn-lee/p/11044540.html

时间复杂度与空间复杂度的理解与计算

小白的我总是搞不清楚 因此做个整理(来源http://data.biancheng.net/view/2.html) 算法是解决某个问题的想法.思路:而程序是在心中有算法的前提下编写出来的可以运行的代码. 算法的运行时间.(称为“时间复杂度”) 运行算法所需的内存空间大小.(称为“空间复杂度”) 时间复杂度 由于是估算算法的时间复杂度,相比而言,循环结构对算法的执行时间影响更大. 所以,算法的时间复杂度,主要看算法中使用到的循环结构中代码循环的次数(称为“频度”).次数越少,算法的时间复杂度越低

时间复杂度和空间复杂度的计算

算法的时间复杂度和空间复杂度合称为算法的复杂度. 1.时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了.并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多.一个算法中的语句执行次数称为语句频度或时间频度.记为T(n). (2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时

数据结构和算法之时间复杂度和空间复杂度

前言 上一篇<数据结构和算法>中我介绍了数据结构的基本概念,也介绍了数据结构一般可以分为逻辑结构和物理结构.逻辑结构分为集合结构.线性结构.树形结构和图形结构.物理结构分为顺序存储结构和链式存储结构.并且也介绍了这些结构的特点.然后,又介绍了算法的概念和算法的5个基本特性,分别是输入.输出.有穷性.确定性和可行性.最后说阐述了一个好的算法需要遵守正确性.可读性.健壮性.时间效率高和存储量低.其实,实现效率和存储量就是时间复杂度和空间复杂度.本篇我们就围绕这两个"复杂度"展开

算法的复杂度包括时间复杂度和空间复杂度分别如何计算?

一 .时间复杂度 一.概念 时间复杂度是总运算次数表达式中受n的变化影响最大的那一项(不含系数) 比如:一般总运算次数表达式类似于这样: a*2n+b*n3+c*n2+d*n*lg(n)+e*n+f a ! =0时,时间复杂度就是O(2n); a=0,b<>0 =>O(n3); a,b=0,c<>0 =>O(n2)依此类推 例子: (1) for(i=1;i<=n;i++) //循环了n*n次,当然是O(n2) for(j=1;j<=n;j++) s++;

php算法基础----时间复杂度和空间复杂度

算法复杂度分为时间复杂度和空间复杂度. 其作用: 时间复杂度是指执行算法所需要的计算工作量: 而空间复杂度是指执行这个算法所需要的内存空间. (算法的复杂性体现在运行该算法时的计算机所需资源的多少上,计算机资源最重要的是时间和空间(即寄存器)资源,因此复杂度分为时间和空间复杂度). 简单来说,时间复杂度指的是语句执行次数,空间复杂度指的是算法所占的存储空间 时间复杂度 计算时间复杂度的方法: 用常数1代替运行时间中的所有加法常数 修改后的运行次数函数中,只保留最高阶项 去除最高阶项的系数 按数量

时间复杂度和空间复杂度

参考博文:http://blog.csdn.net/xiaoxiaopengbo/article/details/51583386 1.时间频度:一个算法执行所消耗的时间.理论上要进行上机测试,但是实际上只需要知道那个算法消耗时间少,那个算法消耗时间多.算法花费时间和执行次数正比(???万一某条语句很耗时间,而另一条语句不耗时间呢?),那个算语句执行次数多,花费时间就越多. 一个算法中语句执行次数称为语句频度或时间频度,记为记为T(n).(用次数反映时间??) 2.时间复杂度:在刚才提到的时间频

[算法技术]算法的时间复杂度与空间复杂度

1.时间复杂度 算法的时间复杂度是衡量一个算法效率的基本方法.在阅读其他算法教程书的时候,对于算法的时间复杂度的讲解不免有些生涩,难以理解.进而无法在实际应用中很好的对算法进行衡量.            <大话数据结构>一书在一开始也针对算法的时间复杂度进行了说明.这里的讲解就非常明确,言简意赅,很容易理解.下面通过<大话数据结构>阅读笔记的方式,通过原因该书的一些简单的例子和说明来解释一下算法的时间复杂度和它的计算方法.          首先从基本定义下手,来了解一下什么是“