走进数据结构和算法(c++版)(1)——算法时间复杂度

算法时间复杂度

  要判断算法的好坏,可以从时间方面进行分析。算法运行的越快,所用的时间越短则算法越好。但是同一个算法在不同的平台上的运行时间不同。那么又该如何进行评判呢?我们采用时间复杂度进行衡量。

算法时间复杂度定义
  在进行算法分析时, 语句总的执行次数 T ( n ) 是关于问题规模 n 的函数,进而分析 T ( n ) n 的变化情况并确定 T ( n ) 的数量。算法的时间复杂度。也就是算法的时间量度,记做: T ( n ) = O ( f ( n ) ) 。它表示随问题规模 n 的增大,算法执行时间的增长率和 f ( n ) 的增长率相同,称作算法的渐近时间复杂度,简称为时间复杂度。 其中 f ( n ) 是问题规模 n 的某个函数。

  简单的理解时间复杂度就是用来表示执行次数 T ( n ) 随问题规模 n 增加的变化趋势。一般情况下,随着 n 的增大, T ( n ) 增长最慢的算法为最优算法。

  那么如何分析一个算法的时间复杂度呢?步骤如下:

  1. 用常数 1 取代运行时间中的所有加法常数。
  2. 再修改后的运行次数函数中,只保留最高阶项。
  3. 如果最高阶项存在且不是 1 ,则去除与这个项相乘的常数。

时间复杂度 O ( 1 )

int a=1,b=3,sum=0;//执行1次
sum=a+b;//执行1次
cout<<"sum="<<sum<<endl;//执行1次

时间复杂度 O ( n )

for(int i = 0; i < n; i++)//执行n次
{
    cout<<i<<endl;
}   

时间复杂度 O ( n 2 )

for(int i = 0; i < n; i++)//执行n^2次
{
    for(int j = 0; j < n; j++)
    {
        cout<<i<<endl;
    }
}   

  综上,我们可以看出,若每层嵌套的时间复杂度为 O ( n ) ,则 n 层嵌套的时间复杂度为 O ( n n )

时间复杂度 O ( l o g n )

int i=1;
while(i<n)
{
    i=i*2;
}

  由于每次执行i乘以2,当 2 x < n 时结束循环。所以总共执行了 x = l o g 2 n 次,所以其时间复杂度为 O ( l o g n )

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

O ( 1 ) < O ( l o g n ) < O ( n ) < O ( n l o g n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n )

最坏情况

  最坏情况运行时间是一种保证,那就是运行时间将不会再坏了。一般在没有特殊说明的情况下,都是指最坏时间复杂度。

平均情况

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

递归算法的时间复杂度求解

  递归算法的时间复杂度的求解方法有很多,我们这里介绍一个比较常用的求解方法——主方法。
  对于递归式:

T ( n ) = a T ( n / b ) + f ( n )

  其中 a 1 b > 1 是常数, f ( n ) 是渐近正函数。

  1. 若对某个常数 ε > 0 ,有 f ( n ) = O ( n ( l o g b a ) ε ) ,则 T ( n ) = Θ ( n l o g b a )
  2. f ( n ) = Θ ( n l o g b a ) ,则 T ( n ) = Θ ( n l o g b a l g n )
  3. 若对某个常数 ε > 0 ,有 f ( n ) = Ω ( n ( l o g b a ) + ε ) ,且对于某个常数 c < 1 和所有足够大的 n a f ( n / b ) c f ( n ) ,则 T ( n ) = Θ ( f ( n ) )

  举个栗子: T ( n ) = 4 T ( n / 2 ) + n ,其中 a = 4 , b = 2 , l o g b a = 2 。当 ε = 1 ,有 O ( n ( l o g b a ) ε ) = O ( n ( l o g 2 4 ) 1 ) = O ( n ) 。符合第一种情况所以 T ( n ) = Θ ( n 2 )

猜你喜欢

转载自blog.csdn.net/hu_weichen/article/details/80417479