zoukankan      html  css  js  c++  java
  • 时间复杂度数量级分析

    时间复杂度数量级分析

    “大 O记法:在这种描述中使用的基本参数是 n,即问题实例的规模,把复杂性或运行时间表达为n的函数。 

    注意:“O”表示量级 (order),比如说“二分检索是 O(logn)的”,也就是说它需要“通过logn量级的步骤去检索一个规模为n的数组”记法 O ( f(n) )表示当 n增大时,运行时间至多将以正比于 f(n)的速度增长。 

    这种渐进估计对算法的理论分析和大致比较是非常有价值的,但在实践中细节也可能造成差异。例如,一个低附加代价的O(n2)算法在n较小的情况下可能比一个高附加代价的 O(nlogn)算法运行得更快。当然,随着n足够大以后,具有较慢上升函数的算法必然工作得更快。 

    O(1) 

    Temp=i;i=j;j=temp; 

    分析: 

         以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。 

         算法的时间复杂度为常数阶,记作T(n)=O(1)。 

         这里的1不是1,只是表示一个常数; 

         如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。

     

    O(n2) 

    2.1. 交换i和j的内容 

    sum=0; (一次) 

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

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

    sum++; (n2次 ) 

    解:T(n)=2*n2+n+1 =O(n2)

     

    2.2. 

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

    { 

    y=y+1; //1 

    for (j=0;j<=(2*n);j++)(2*n+1次) 

    x++; //2 

    } 

    解: 语句1的频度是n-1 

          语句2的频度是(n-1)*(2*n+1)=2*n2-n-1 

          f(n)=2*n2-n-1+(n-1)=2*n2-2 

          该程序的时间复杂度T(n)=O(n2).

      

    O(n) 

    2.3. 

    a=0; 

    b=1;                              //1 

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

    { 

    s=a+b;            //3 

    b=a;             //4 

    a=s;             //5 

    }

     

    解: 语句1的频度:2, 

          语句2的频度: n, 

          语句3的频度: n-1, 

          语句4的频度:n-1, 

          语句5的频度:n-1, 

          T(n)=2+n+3(n-1)=4n-1=O(n).

     

    O(log2n ) 

    2.4. 

    i=1;          //1 

    while (i<=n) 

    i=i*2;      //2 

    解: 语句1的频度是1, 

          设语句2的频度是f(n), 则:2f(n)<=n;  f(n)<=log2n 

          取最大值f(n)= log2n, 

          T(n)=O(log2n )

     

    O(n3) 

    2.5. 

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

    { 

      for(j=0;j<i;j++) 

      { 

         for(k=0;k<j;k++) 

              x=x+2; 

      } 

    } 

    解: 当i=m, j=k的时候,内层循环的次数为k当i=m时, j 可以取 0,1,...,m-1 , 所以这里最内循环共进行了0+1+...+m-1=(m-1)m/2次 ,所以i从0取到n, 则循环共进行了: 

           0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6所以时间复杂度为O(n3). 

        我们还应该区分 算法的最坏情况的行为和期望行为。如快速排序的最坏情况运行时间是 O(n2),但期望时间是 O(nlogn)。通过每次都仔细地选择基准值,我们有可能把平方情况 (即O(n2)情况)的概率减小到几乎等于 0。在实际中,精心实现的快速排序一般都能以 (O(nlogn)时间运行。

     

    下面是一些常用的记法: 

        访问数组中的元素是常数时间操作,或说O(1)操作。一个算法 如 果能在每个步骤去掉一半数据元素,如二分检索,通常它就取 O(logn)时间。用strcmp比较两个具有n个字符的串需要O(n)时间。常规的矩阵乘算法是O(n3),因为算出每个元素都需要将n对元素相乘并加到一起,所有元素的个数是n2 

        指数时间算法通常来源于需要 求出所有可能结果。例如,n个元素的集合共有2n个子集,所以要求出所有子集的算法将是O(2n)的。指数算法一般说来是太复杂了,除非n的值非常小,因为,在 这个问题中增加一个元素就导致运行时间加倍。不幸的是,确实有许多问题 (如著名的“巡回售货员问题” ),到目前为止找到的算法都是指数的。如果我们真的遇到这种情况,通常应该用寻找近似最佳结果的算法替代之。

     

    技巧1: 

    For(i=1; i<n; i*=2) 

    { 

    } 

    那么这个程序片段的时间复杂度就是:O(log2n);

      

  • 相关阅读:
    堆栈学习
    需要阅读的书籍
    Rust Book Lang Ch.19 Fully Qualified Syntax, Supertraits, Newtype Pattern, type aliases, never type, dynamic sized type
    Rust Lang Book Ch.19 Placeholder type, Default generic type parameter, operator overloading
    Rust Lang Book Ch.19 Unsafe
    Rust Lang Book Ch.18 Patterns and Matching
    Rust Lang Book Ch.17 OOP
    Rust Lang Book Ch.16 Concurrency
    Rust Lang Book Ch.15 Smart Pointers
    HDU3966-Aragorn's Story-树链剖分-点权
  • 原文地址:https://www.cnblogs.com/hpuwangjunling/p/4386531.html
Copyright © 2011-2022 走看看