复杂度分析方法

一个例子:

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)

猜你喜欢

转载自blog.csdn.net/sujins5288/article/details/85334295