数据结构算法复杂度详解

算法复杂度问题

引例

第一种算法:(1+(n+1)+n)=2n+2次

int i,sum=0,n=100;      //执行1次
for(i=1;i<=n;i++){      //   执行n+1词
    sum+=i;             //执行n次
}

第二种算法: 1+1=2次

int sum=0,n=100;        //执行1次
sum=(1+n)*n/2;          //执行1次

如果我们把循环看作一个整体,忽略头尾判断的开销,那么这两个算法就是n和1的差距;
算法的复杂度,我们侧重的是研究算法随着输入规模的扩大增长量的一个抽象,而不是精确的定位执行了多少次;

列:

int i,j,x=0,sum=0,n=100;
for(i=1;i<=n;i++){      //执行n+1次
    for(j=1;j<=n;j++){  //当外层i每执行1次,内层j执行n+1次
        x++;            //执行n次
        sum=sum+x;
    }
}

此算法的复杂度就为$n{2}$,也就是$1002$次;

我们在分析算法的运行时间时,重要的是把基本操作的数量和输入模式关联起来。

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

通用攻略:

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


常数阶

int sum=o,n=100;
printf("第一条");
printf("第二条");
printf("第三条");
printf("第四条");
printf("第五条");
printf("第六条");
sum = (i+1)*n/2;    //只有这一句影响了n

因为T(n)是关于问题规模n的函数,所以时间复杂度为:O(1)


线性阶

int n=100;      
for(int i=1;i < n;i++){     
    printf("hello guys");   //执行n次          
}

因为循环体中的代码需要执行n次,所以时间复杂度为:O(n)


平方阶(1)

int n=100;
for(int i=0;i < n;i++){         //执行n次
    for(int j=0;j < n;j++){     //执行n*n次
        printf("hello guys");
    }
}

因为循环体中的代码需要执行n*n次,所以时间复杂度为:O($n^{2}$)


平方阶(2)

int n=100;
for(int i=0;i< n;i++){          //执行n次
    for(int j=i;j< n;j++){      //当i=n时,j执行n-1次
        printf("hello guys");
    }
}

分析:

内循环总的执行次数应该是:
$-n+(n-1)+(n-2)+...+1=frac{n(n+1)}{2}$
$frac{n(n+1)}{2}=frac{n^2}{2}+frac{n}{2}$

根据大O攻略:
第一条忽略,因为没有常数相加。
第二条只保留最高项,所以$frac{n}{2}$去掉。
第三条,去除与最高项相乘的常数,最终得O($n^{2}$)。


对数阶

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

由于$2{x}=n$得到$x=log_2{n}$,所以,这个循环的时间复杂度为O($log{n}$)。


函数时间复杂度分析

int n=100;
for(int i=0;i< n;i++){
    function(i);
}
void function(int count){
    printf("hello guys");
}

函数的复杂度是O(1),而for循环的调用,所以时间复杂度是O(n)。

int n++;
function(n);

for(int i=0;i< n;i++){
    function(i);
}
for(int i=0;i< n;i++){
    for(j=i;j< n;j++){
        printf("hello guys");
    }
}
void function(int count){
    printf("hello guys");
}

$1$+$1$+$n$+$n{2}$=**O($n{2}$)**

总结:

O(1) < O($log{n}$) < (n) < O($nlog{n}$) < O($n^2$) < O($n^3$) < O($2^n$) < O($n!$) < O($n^n$)

原文地址:https://www.cnblogs.com/apebro/p/12573574.html