算法的时间复杂度计算方法

算法时间复杂度评估的一般法则

2020/8/18

若有过错,请评论斧正。

法则一:for循环法则

一次for循环的运行时间,最多是该for循环内语句(包括测试)的运行时间乘以迭代的次数。

Eg:

#include<stdio.h>
int main(){
int i;
int b = 0;
int a = 1;
    for(i=0;i<N;i++)
    {
        b = b + i;
        a = a + 1;
    }
    return 0;
}

for循环的迭代次数为N,for循环内有两个加法执行。所以根据for循环法则,该for循环的运行时间是

\[2 * N \]

所以该for循环的运行时间是:

\[O(N) \]

法则二:嵌套for循环

从里向外分析循环。在一组嵌套循环内部的一条语句总的运行时间为该语句的运行时间乘以该组所有的for循环的大小的乘积。

Eg:

#include<stdio.h>
int main(){
int i;
int j;
int a = 1;
    for(i=0;i<N;i++)
    {
      for(j=0;j<M;j++)
      {
          a++;
      }
    }
    return 0;
}

可以理解为一个组合的问题:语句a++的执行时间是一个单元,但a++在内循环中,可以用法则一求出内循环的执行时间是

\[1*M \]

把内循环看做一次执行,该次执行要使用 \(M\) 的时间。在此使用法则一得到运行时间是

\[N*M \]

所以该嵌套for循环的运行时间是:

\[O(M*N) \]

当M=N的时候就是

\[O(N^2) \]

法则三:顺序语句

将各个语句的运行时间求和即可,其中最大值便是所得的运行时间

Eg

#include<stdio.h>
int main(){
int i;
int j;
int a = 1;
    for(i=0;i<N;i++)
    {
      for(j=0;j<M;j++)
      {
          a++;
      }
    }
    for(j=0;j<N;j++)
    {
        a++;
    }
    return 0;
}

该例子有两部分组成 第一个部分是嵌套for循环,时间复杂度是N*M 第二个是for循环,时间复杂度是 N 两部分相加,时间复杂度是 M*N+N,也就是

\[O(M*N) \]

法则四:if/else语句

一个if语句的运行时间从不超过判断再加上分支中运行时间最长的部分。可由前面的法则推导而来。

当遇到这样的情况时,需要计算循环的执行次数,因为他不如i++那么显而易见的表明了循环的执行次数。

#include<stdio.h>
int main(){
    int a = 1;
    while(a<16)
    {
        a*2;
    }
    return 0;

当循环停止的时候,a>=16。由此可以得出一个等式

\[a*2^x >=16 \]

等式中的x,便是我们所要求的循环执行次数。解出等式

\[x=log{_2}{^{16/a}} \]

其中16/a是个常数,可以直接计算出来用n来代替。式子变成如下

\[x=log{_2}{^{n}} \]

也就是

\[O(log{_2}{^{n}}) \]

其中O()代表的是算法执行时间随着数据输入量的变化模型。

\( O(1) 代表该算法的执行时间永远是一个常数,不随着数据量的多少而改变 \\ O(N) 代表该算法的执行时间随着输入数据量的多少呈线性增长 \\ O(N^2) 代表该算法的执行时间随着输入数据量的多少呈二次增长 \\ O(log{_2}{^{n}})代表该算法的执行时间随着输入数据量的多少呈对数增长 \\ \)

当然,还有指数增长等。对于算法的选择在结合实际的情况下,应该选择最符合当前数据量或未来数据量的最佳增长模型。

posted @ 2022-08-18 16:11  黑猫魔法师  阅读(279)  评论(0)    收藏  举报