同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率。算法分析的目的在于选择合适算法和改进算法。
算法复杂度分为时间复杂度和空间复杂度。其作用: 时间复杂度是指执行算法所需要的计算工作量;而空间复杂度是指执行这个算法所需要的内存空间。(算法的复杂性体现在运行该算法时的计算机所需资源的多少上,计算机资源最重要的是时间和空间(即寄存器)资源,因此复杂度分为时间和空间复杂度)。
一、时间复杂度:执行一个算法,代码运行的次数和问题规模之间的函数关系,用O表示。
规则1:只保留最高阶项
规则1:不要系数
例1:
{++x;s=0;}
以上两条单个语句代码执行的次数均为1,该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶,记作O(1)。
注:如果算法的执行时间不随着问题规模n的增加而增长,就是与n无关,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
例2:
int a=0;
int b=1;
int s=0;
for(int i=0;i<n;i++)
{
s=a+b;
}
for循环执行n次,循环体也执行n次,即记作O(n)。
例3:
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(n^3)。
例4:
for(int i=1;i<=n;i*=2)
{
......
}
i从1到n,i*=2,即1,2,4,8,16,…,n计算代码执行的次数,设次数为x,则得到
2^x=n,x=logn,时间复杂度记作O(logn)。
例5:递归调用相关的时间复杂度的计算。
int Fun(int n) //时间复杂度为O(n)
{ //空间复杂度为O(n)
if(n<=1)
{
return n;
}
else return F(n-1)+1;
}
int Fun(int n) //时间复杂度为O(n)
{ //空间复杂度为O(n)
if(n<=1)
{
return n;
}
else return F(n-2)+1;
}
int Fun(int n) //时间复杂度为O(logn)
{ //空间复杂度为O(n)
if(n<=1)
{
return n;
}
else return F(n/2)+1;
}
算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好反映出算法的优劣与否。因此,作为程序员,掌握基本的算法时间复杂度分析方法是很有必要的。
二、空间复杂度:执行一个算法,需要额外的辅助空间和问题规模之间的函数,用O来表示。