一个例子:
1. int dealData(int n){
2. int i=0;
3. for(int k=0;k<n:k++ ){
4. println(k);}
5.}
假设每行代码执行的时间为 until_time;
那么计算这个方法执行的总时间该是多少了?
第二行执行的时间为一个until_time,第三四行执行的时间为2n;所有总的执行时间为:T(n)=(2n+1)*unil_time;
尽管我们不知道每行代码的具体执行时间until_time是多少,但我们从上述公式可以看出,执行时间跟每行代码的执行次数是成正比。所以我们可以得到以下推论:T(n)=O(f(n)),其中T(n)我们在上边已经说过,代表代码执行总时间,n代表数据规模,O代表T(n)与f(n)表达式的关系成正比。大O表示的不是真正的代码执行时间,而是代码执行时间随数据增长的一个趋势,所以称为渐进时间复杂度,简称时间复杂度。当n很大时,公式中的常量,系数都对总体的增长趋势来说,影响已不大,故当数据量足够大时,表达式的常量,系数可直接省略掉,以上公式可变为:T(n) = O(n);
对于 O(n),O(n2)的时间复杂度都比较好分析,以下只讲一下对数的复杂度分析:
int i=1;
while(i<n){
i=i*2;
}
我们首先来探究下规律:第一次的时候,i=1*2;第二次时i=2*2 。。。即 2^0,2^1,2^2...所以 n=2^x
故O(n) = O(log2^n)。因为复杂度中系数是可以省略的,所以无论是log2^n,log3^n,都可简写为log^n对数据,即以上O(n)=O(log^n).
再来讲与前面不同的一种时间复杂度,对于以下代码:
int cal(int m,int n){
for(int i=0;i<m;i++){
print(m);
}
for(int k=0;k<n;k++){
print(k)
}
}
对于这段代码的时间复杂度,因为不知道m跟n到底哪个大,所以不能把m或者n当做常数省略掉,这段代码的时间复杂度O(n)=O(m+n)
空间复杂度分析:
void printData(int n){
int [] a=new int[n];
for(int i=0;i<a.size;i++)
a[i] = i*2;
}
}
跟时间复杂度分析一样,我们可以看到,上述代码中数组开了n个空间,而其他的代码占用空间都是常量级的,所以这段代码的空间复杂度为O(n)