时间复杂度

1.时间复杂度判断 一般法则

  1.1----for循环

   for循环的运行时间至多是for循环内部代码的运行时间乘for循环的迭代次数

    

    public static int sum(int n){

        int partOne;

         partOne = 0;

         for (int i=1 ;i<n;i++){

             partOne += i*i*i;

         }
         return partOne;
    }

   上例代码for循环的运行 n*1次所以时间复杂度为  O(n)

  1.2---嵌套for循环法则

   分析嵌套循环的诀窍是  从里向外分析这些循环:

        言语不足以表达,且看画图大法:

      

for (int i=1 ;i<n;i++){-----------------------------n    
             for(int j=1;j<n;j++){ -------------------n
                 for(int x=1 x<3 ;x++){----------      3
                     partOne += i*i*i;
                 }
             }
         }

   所以时间复杂度计算应该为 3*n*n=3n^2    O(n^2)

   1.3----顺序语句

   对于顺序语句在计算时间复杂度时,总的时间复杂度等于最大的时间复杂度

  

void aFunc(int n) {
  ---------------------------------------------------------
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            printf("Hello, World!\n");    ---------时间复杂度为O(n^2)
        }
    }  
  ---------------------------------------------------------
    for(int j = 0; j < n; j++) {
        printf("Hello, World!\n");     ---------时间复杂度为O(n)
    }
--------------------------------------------------------- }

  上例中总的时间复杂度为 max(O(n^2),O(n)) =  O(n^2)

   1.4----if else

  对于条件判断的语句计算时间复杂度,那条路径的时间复杂度最大,那么这条路径的时间复杂度就是条件语句的时间复杂度。

void aFunc(int n) {
    if (n >= 0) {
        ---------------------------------------------------------第一条路径----------
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                printf("输入数据大于等于零\n");             >>>>>>>>>>>>>>时间复杂度O(n^2)
            }
        }
    ----------------------------------------------------------------------------- } else {
    ---------------------------------------------------------第二条路经---------- for(int j = 0; j < n; j++) { printf("输入数据小于零\n"); >>>>>>>>>>>>>>时间复杂度O(n) }
    ---------------------------------------------------------------------------- } }

  上例中第一条时间复杂度为O(n^2) 第二条路径的时间复杂度为O(n) 所以整段代码的时间复杂度为 max(O(n^2),O(n)) = O(n^2)

   1.5 时间复杂度为log n的例子

void sum(int n){
  int x = 0 ;
   for(int i=1; i<n; i*=2){
     x += i;
   }
}

  代码的运行次数为  2^x = n   =>>>   x = log n 次

  所以上述代码的时间复杂度为O(log n)

   1.6 最坏、平均、时间复杂度

   我们上述计算的时间复杂度基本上都指的时   最坏的时间复杂度   

   所以下段代码的     最坏时间复杂度为: O(n)

   什么是最好的时间复杂度,我们可以浅显的理解为 需要在数组中找的 x 就是在数组的第一位 所以最好时间复杂度为 O(1)

    

 
//在一个数组中查找变量 x 出现的位置,如果找到了,就马上跳出循环,
//返回它的位置值;如果找不到,就返回 -1
int find(int[] array, int n, int x) {
   int i = 0;
   int pos = -1;
   for (; i < n; ++i) {
    if (array[i] == x) {
        pos = i;
        break;
     }
   }
   return pos;
 }

  最好、最坏情况时间复杂度都是极端情况下的代码复杂度,发生的概率很小

  要查找的变量 x 在数组中的位置,总共有 n+1 种情况:在数组的 0~n-1 位置中和不在数组中。我们把每种情况下,查找需要遍历的元素个数累加起来再除以 n+1,就可以得到需要遍历的元素个数的平均值

  所以平均时间复杂度为:O((1+2+3+......n+1)/n+1 ) =O( n(n+3)/2(n+1) )= O(n/2 ) = O(n)

  所以平均时间复杂度也叫加权平均时间复杂度(亦称为期望时间复杂度)

// array 表示一个长度为 n 的数组
// 代码中的 array.length 就等于 n
//往一个数组中插入数据的功能,当数组满了以后,
//也就是 count == array.length 的时候,我们用 for 循环遍历数组求和,
//再将新的数据插入
 int[] array = new int[n];
 int count = 0;
 
 void insert(int val) {
   if (count == array.length) {
      int sum = 0;
     for (int i = 0; i < array.length; ++i) {
         sum = sum + array[i];
      }
      array[0] = sum;
      count = 1;
   }
 
   array[count] = val;
   ++count;
 }

  上述例子中   

    最坏时间复杂度为 O(n)     最好时间复杂度为 O(1)  平均时间复杂度为:因为每次可以插入的几率都为 1/n+1 所以平均时间复杂度为   O( (n+1) / (n+1) ) = O(1) 

  

 

posted on 2019-03-26 13:31  YOOC  阅读(461)  评论(0)    收藏  举报

导航