时间复杂度的定义是:如果一个问题的规模是n,解决这一问题所需算法所需要的时间是n的一个函数T(n),则T(n)称为这一算法的时间复杂度。
算法中基本操作的执行次数。既然是T(n)的函数,随着模块n的增大,算法执行的时间的增长率和T(n)的增长率成正比,所以T(n)越小,算法的时间复杂度越低,算法的效率越高。 通过时间的复杂度来看算法执行的好坏。
时间复杂度:全称渐进式时间复杂度,表示算法的执行时间与数据规模的增长关系; 空间复杂度:全称渐进式空间复杂度,表示算法的存储空间与数据规模增长关系;
通俗来讲:
int i=0,n=100; /*执行了一次*/
i=n/2+n; /*执行了一次*/
printf("i=%d",i); /*执行了一次*/
非常容易分析出这段代码一共执行了3次,那么时间复杂度就是O(3)吗,这样想是错误的,回头看之前计算时间复杂度方法,它是f(n)=3,所以应该把3改为1,即O(1)。再来一段代码:
int i=0,n=100; /*执行了一次*/
i=n/2+n; /*执行了一次*/
printf("i=%d",i); /*执行了一次*/
printf("i=%d",i); /*执行了一次*/
printf("i=%d",i); /*执行了一次*/
printf("i=%d",i); /*执行了一次*/
printf("i=%d",i); /*执行了一次*/
这段代码一共执行了7次,那么时间复杂度为多少呢,还按照上面所说的,它是f(n)=7,把7改为1,即O(1)。比如像这种代码是具有恒定的执行时间的,也就是代码不会因为问题规模n的变化而发生变化,这里都记为O(1).
void fun(int n)
{
int i=1,j=100;
while(i<n)
{
++j;
i+=2;
}
}
显然n确定以后,循环的开始结束都是与i有关的,且每次自增2,假设m次后结束循环,那么i应该等于1+2m,那么就有n=1+2m,因为要是执行次数,也就是解得m=(n-1)/2,此时可以看出n/2增长的是最快的项需要把前面的系数除掉即可得到O,即(n/2)/(1/2)=n,得O(n). 接下来个复杂点的:
int i=1;
while(i<n)
{
i=i*2;
}
推导时间复杂度,最重要的就是要分析算法的执行次数。这里i起始值为1,每次都乘2,也就意味着每次都会距离n近一些,那么何时超过n而终止循环呢,是i22222...*2>n,那么假设k次之后大于n,就有2^k=n,得出k=logn。 再来一段代码:
int i,j,x=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
x++;
}
外循环执行n次,内循环也是执行n,则O(n^2). 最后来一段代码:
int i,j,x=0;
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
x++;
}
由于当i=0,时内循环执行了n次,i=1时,执行了n-1次,...i=n-1时,执行了1次,那么总次数为 n+(n-1)+(n-2)+..+1=n(n+1)/2,那么就是n^2/2,即O(n^2).