时间复杂度

时间复杂度分析

  我们经常涉及到的时间复杂度,通常有:O(1),O(n),O(lgn),O(nlogn),O(n^2),这里面O代表的是算法运行的时间与变量N的数学关系。
例如我们简单的写一个段相加求和的代码:
    int sum(int a ,int b){
      int sum = a+b;
      return sum;
    }
  我们说这个方法的时间复杂度为O(1),换句话说,执行这段代码一次的时间 就是所需的时间。这里就是函数的变量为常数1,也就是1次。当然还有2次,3次,像这样能有具体,有限界的数我们都归为时间复杂度为O(1)
  所以说,O描述的是算法的运行时间和输入数据之间的关系。
  我们接着看段代码:
    int sum( int[]  array){
      int sum = 0;
      for(int arrayItem: array)
        sum+=arrayItem;
      return sum
    }
  这是一段遍历数组求和的代码,数组的长度这里未知,我们假设为n,那么这段代码执行次数就为n次,执行完这段代码所需要的时间和执行次数n成线性关系。
  执行完这段代码具体所需要的时间:
    先是int sum = 0,初始化sum数值为0,假设时间为a。之后遍历数组,假设每次遍历求和花的时间都为bn次也就花费时间  b * n 。最后返回sum值时间为c
  那么,总的时间 :t = a + b * n +c
  这就是执行完这段代码所需要的时间和执行次数n成的线性关系。我们舍去abc这些常量,把所花费的时间和变量n的关系就表示成O。即,O(n)
 
  为什么不用线性关系,而是舍去常数用时间复杂度?
  因为虽然我们常数时间具体代表执行了哪几段代码的时间,但我们不知道其具体花费的时间是多少,在每个不同环境上都会有不同的时间。像上面遍历数组求和的代码中,a、bc,知道它们分别代表这初始化sum,sum加操作和返回sum值得时间,但具体时间很难定义。这对于我们衡量一段程序代码时间没有多大的意义,所以通常我们衡量一段程序代码用时间复杂度计算。
  所以,查看一个算法的时间复杂度将常数舍去看t和n的关系。
    t = a =》 O(1)
    t = a + b * n +c =》 O(n)
    t = a + b * n *n+c =》 O(n^2)
 
    考虑最坏的情况
  有人会说时间复杂度大就越慢,其实不是这样的,例如:
     t = a + b * n +c =》 O(n)
     t = a + b * n *n+c =》 O(n^2)
  如果说上面的 O(n)项的常量都很大,具体成立线性关系t = 1000 + 2000 * n +3000 。而O(n^2)项的t = 1 + 2 * n  * n+3 ,当我们输入的n比较小时,很明显是O(n)项的时间会比较多。但通常我们写程序代码时通常多会考虑最坏的情况,在这里也就是上面的n接近于无穷大,这时后者肯定花更多的时间,常数这些都可以不考虑。所以,时间复杂度小可以说一个程序算法好而不能说它快。

posted @ 2018-09-14 00:24  不爱熬夜的猫  阅读(409)  评论(0编辑  收藏  举报