zoukankan      html  css  js  c++  java
  • 代码的时间和空间复杂度

    如何评估代码的复杂度

    代码具有两种复杂度衡量方向,一个是时间复杂度,一个是空间复杂度

    一,时间复杂度
    定义:如果一个问题的规模是n,解决这一问题的某一算法所需要的时间为T(n),它是n的某一函数T(n)称为这一算法的“时间复杂性”。

    性质:
    1,渐近时间复杂性:当输入量n逐渐加大时,时间复杂性的极限情形。

    T(n)=O(f(n))

    T(n)表示为时间复杂度

    大O记法表示该函数具有上限

    f(n)表示问题本身的规模n造成的时间消耗上的函数关系

    2,推导大O阶方法

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

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

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

    3,具体情况:

    常数阶:顺序执行没有循环

    线性阶:具有循环,时间复杂度和循环的次数有关
    int i;

    for(i = 0; i < n; i++){

    /*时间复杂度为O(1)的程序步骤序列*/

    }
    //循环n次,总的时间复杂度是O(n)

    对数阶:由于每次count乘以2之后,就距离n更近了一分。 也就是说,有多少个2相乘后大于n,则会退出循环。 由2^x=n 得到x=logn。 所以这个循环的时间复杂度为O(logn)。

    int count = 1;

    while (count < n){

    count = count * 2;

    /*时间复杂度为O(1)的程序步骤序列*/

    }

    平方阶:
    而对于外层的循环,不过是内部这个时间复杂度为O(n)的语句,再循环n次。所以这段代码的时间复杂度为O(n^2)。如果外循环的循环次数改为了m,时间复杂度就变为O(mXn)所以我们可以总结得出,循环的时间复杂度等于循环体的复杂度乘以该循环运行的次数。

    例1:
    int i, j;

    for(i = 0; i < n; i++){

      for(j = 0; j < n; j++){

    /*时间复杂度为O(1)的程序步骤序列*/

      }

    }//内外循环无关,时间复杂度内外相乘


    例2:
    int i, j;

    for(i = 0; i < n; i++){

      for(j = i; j < n; j++){ /*注意j = i而不是0*/

      /*时间复杂度为O(1)的程序步骤序列*/

      }

    }//内外循环有关系,需要逐一相加,得出关系式,并且使用大O推导,得出最终的时间复杂度:

    由于当i=0时,内循环执行了n次,当i = 1时,执行了n-1次,……当i=n-1时,执行了1次。所以总的执行次数为:

    用我们推导大O阶的方法,第一条,没有加法常数不予考虑;第二条,只保留最高阶项,因此保留时(n^2)/2; 第三条,去除这个项相乘的常数,也就是去除1/2,最终这段代码的时间复杂度为O(n2)。

    立方阶:

    int i, j;

    for(i = 1; i < n; i++)

    for(j = 1; j < n; j++)

    for(j = 1; j < n; j++){

    /*时间复杂度为O(1)的程序步骤序列*/

    }//时间复杂度是O(n^3)

    4,常见的时间复杂度

    常见的时问复杂度如表所示:

    常用的时间复杂度所耗费的时间从小到大依次是:

    5,最坏情况和平均情况

    最坏情况运行时间是一种保证,那就是运行时间将不会再坏了。 在应用中,这是一种最重要的需求, 通常, 除非特别指定, 我们提到的运行时间都是最坏情况的运行时间。

    平均运行时间是所有情况中最有意义的,因为它是期望的运行时间。

    注意:一般在没有特殊说明的情况下,都是指最坏时间复杂度。


    二,空间复杂度

    算法的空间复杂度通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记作:S(n)= O(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。

    一般情况下,一个程序在机器上执行时,除了需要存储程序本身的指令、常数、变量和输入数据外,还需要存储对数据操作的存储单元,若输入数据所占空间只取决于问题本身,和算法无关,这样只需要分析该算法在实现时所需的辅助单元即可。若算法执行时所需的辅助空间相对于输入数据量而言是个常数,则称此算法为原地工作,空间复杂度为0(1)。//即算法计算的辅助空间是已经确定分配好的固定空间。

    三,时间和空间复杂度计算规则

    1,加法规则

    T(n,m) = T1(n) + T2(m) = O(max{f(n), g(m)})//两个时间复杂度相加,取最大者为和

    2,乘法规则

    T(n,m) = T1(n) * T2(m) = O(max{f(n)*g(m)})//

    3,一个经验

    复杂度与时间效率的关系:
    c(常数)     <     logn     <     n     <     n*logn     <  n^2  <  n^3  < 2^n  <  3^n     <     n!
    l------------------------------l--------------------------l--------------l
    较好                                                 一般                                          较差


    四,常用算法的时间复杂度和空间复杂度

    参考文章:https://www.cnblogs.com/silence-x/p/10544072.html

    业精于勤,荒于嬉,行成于思,毁于随~
  • 相关阅读:
    面试题:使用存储过程造10w条测试数据,数据库插入10w条不同数据
    面试题:如何造10w条测试数据,在数据库插入10w条不同数据
    httprunner 2.x学习9-生成测试报告ExtentReport('dict object' has no attribute 'meta_data'问题已解决)
    httprunner 2.x学习8-参数化(引用 debugtalk 函数)
    httprunner 2.x学习7-参数化(引用外部csv数据)
    httprunner 2.x学习6-参数化与数据驱动
    httprunner 2.x学习5-测试用例集(testsuite)
    httprunner 2.x学习4-测试用例分层
    启动Hadoop HA Hbase zookeeper spark
    如何运行Spark程序
  • 原文地址:https://www.cnblogs.com/yu-tang/p/12084618.html
Copyright © 2011-2022 走看看