Analyzing the complexity of the algorithm

1, the algorithm: Algorithm describing solve a particular problem solution step, expressed as a finite sequence of instructions in a computer, and each represents one or more instruction operations.

So what kind of algorithm can be called a good algorithm, which means there is no criterion to judge the quality of an algorithm?

Prior to this, let's first take a test:

  Two ways to achieve seeking Pei Fibonacci series value of the first n terms of a recursive manner mode, a second mode with normal cyclic manner.

  Prior to get the results, you guess that way results faster, or as fast?

  Test code as follows (JavaScript):

/ * * 
 * 1, recursive Fibonacci numbers listed: 
 * = 1,1,2,3,5 ... n items of the first item n-1 + n-2-item 
 * * / 
function recursionFbi (n) {
     IF (n-<. 3) return . 1 ;
     IF (n-==. 3) return 2 ;
     // the console.log ( "recursive n-:", n-); 
    return recursionFbi (. 1-n-) recursionFbi + (2-n- ); 
} 

/ * * 
 * 2, the cycle realization Pei Fibonacci series 
 * = 1,1,2,3,5 ... n items of the first item n-1 + n-2-item 
 * * / 
function circleFbi (n) { 

    IF (n-<. 3) return . 1 ;
     var A =. 1, B =. 1, C = 0;
    for (var i = 0; i < n; i++){
        if (i > 1){
            c = a + b;
            a = b;
            b = c;
        }
        console.log("循环i: ", i, ", c: ", c);
    }
    return c;
}
View Code

Several tests figure is entered here, the result is substantially recorded for comparison.

Of course, each test is calculated the same time a number is not necessarily the same, with the current test computer hardware configuration, and other applications to open a certain relationship with.

When the input when n = 51, the following test results screenshot:

There are a number of other statistics n input values:

   The above requirements Pei Fibonacci series in two ways, demonstrated by the loss of value of the time difference amazing! Why is there such a big difference? This reflects the operating efficiency of a good algorithm to make the program more effective, a bad algorithm for the program is simply a disaster! Just difference between these two ways of algorithm, and then wait for the next analysis.

 

2, now, for us to say how good or bad a rough estimate of an algorithm.

  We design requirements for the algorithm is: accuracy, readability, robustness, high time efficiency, low storage capacity .

  Thus for an algorithm, before we run, it may be determined from analysis of five angles, and the main storage from the time efficiency point of view to elaborate the following:

  • Time complexity (Time Complexity) : the estimated number of execution program instructions (execution time)
  • Control complexity (Space Complexity) : estimate the required storage space occupied

  

  Big O notation is a rough model, can help us to quickly estimate the efficiency of an algorithm, we use it to describe the time complexity of the algorithm.

  Common time complexity of these:

  When large O derivation method, for constant order, we replaced by a constant 1; multiple-order term, leaving only the highest order term; the constant removal of the highest order term. Figure:

  

Several examples of this paste is used to calculate complexity of practice time (JavaScript):

//算法复杂度:O(n)
function testCount1(n){
    //指令计数:多个if算作一个指令
    if (n > 10){
        console.log("n > 10")
    }
    else if(n > 5){
        console.log("n > 5")
    }
    else{
        console.log("n <= 5")
    }

    //指令计数:1 + n + n + n = 3n + 1
    for (var i = 0; i < n; i++){
        console.log("...testCount1...")
    }
}

//算法复杂度:O(logn)
function testCount3(n){
    //指令计数:n/2 = log2(n)
    //n=2 -> 1;  n=4->2;    n = 8->3;   n = 16->4;  n = 32->6
    //1=log2(2); 2=log2(4); 3=log2(8);  4=log2(16);  6=log2(32)
    while((n = n / 2) > 0){
        console.log("***testCount3***");
    }
}

//算法复杂度:O(nlogn)
function testCount4(n){
    //指令计数:1 + 2*log2(n) + log2(n) * (1+3n) = 1 + 3log2(n) + 3n*log2(n)
    for (var i = 1; i < n; i = i * 2){
        //1 + 3n
        for (var j = 0; j < n; j++){
            console.log(">>>testCount4>>>")
        }
    }
}

//算法复杂度:O(n^2)
function testCount2(n){
    //指令计数:1 + 2n + n * (1+3n) = 1 + 3n + 3n^2 = 3n^2 + 3n + 1
    for (var i = 0; i < n; i++){
        for (var j = 0; j < n; j++){
            console.log("...testCount2...")
        }
    }
}
View Code

 常见的时间复杂度所耗时间的大小排列如下:

 

3、掌握了大O推导法,我们用大O表示法来论证本文最开始计算裴波那契数列的两种算法的区别:

 3.1 递归方式算法,先看下图:

  

  可以得出,这里的递归方式算法用大O表示法来表示,它属于指数阶,可以粗略表示为:O(n) = 2^n

  3.2 而第二种循环方式算法为线性阶的,用大O表示法为:O(n) = n

  3.3 我们对比一下指数阶和线性阶的函数曲线图就知道,n系数越大,这两种方式的最后的结果相差越大。

    所以当n越大时,递归方式算法的计算次数呈指数级上升,最后次数结果越大,时间损耗数也就越多。

 

测试Demo地址:https://github.com/xiaotanit/Tan_DataStruct

Guess you like

Origin www.cnblogs.com/tandaxia/p/10919609.html