算法的时间复杂度

算法的时间复杂度

时间复杂度:咱们将算法执行运算的操做数丢弃掉低阶项,再去掉全部的系数.java

在它前面加上一个O,就是大O表示法.算法

int n = 100;
int a = 10;
System.out.println(a);
//总共执行3次
复制代码

没有更低阶的项了,系数是3, 去掉系数3, 因此时间复杂度是 O(1)数组

int n = 100;
        int a = 10; 
        for (int i = 0; i < n; i++) {  //n次
            System.out.println(a);     //n次
        }
        System.out.println(a);
        //总共执行2n + 3次
复制代码

去掉低阶项3,再去掉系数2,因此它的时间复杂度就是O(n)markdown

int n = 100;
        int a = 10;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.println(a);
                System.out.println(a);
            }
        }
        System.out.println(a);
//2n^2+3次
复制代码

去掉低阶项3,再去掉系数2, 因此它的时间复杂度是O(n2)数据结构

常见的时间复杂度

image-20200622213828555

即便系数很大,可是对于咱们来讲都没有意义,只要n的数量级够大,总能抹平低阶项和系数带来的影响 , 高阶项才是函数增加的主要影响因素.函数

增加速度

image-20200622214111780

通常法则

for循环

假设循环体的时间复杂度为O(n),循环次数为m,则这个循环的时间复杂度为O(m*n).spa

image-20200622214712730

时间复杂度为O(n*1), 即O(n).指针

嵌套的for循环

对于多个循环,假设循环体的时间复杂度为O(n),各个循环的循环次数分别为a,b,c,则这个循环的时间复杂度为O(n*a*b*c...).code

分析的时候应该从里向外分析这些循环.orm

image-20200622214955082

时间复杂度为O(1*m*n), 即O(m*n)

顺序语句

各个语句的运行时间求和便可(或者说取最大值).

image-20200622215245744

时间复杂度为O(2+n+n2+1),即为 O(n2).

分支语句

总的时间复杂度等于其中时间复杂度最大的路径的时间复杂度

image-20200622215630523

这里若是运气好,第一次判断进入if就结束了,那么时间复杂度就是O(n),

可是算法的时间复杂度是按最坏的状况来算的,因此看时间复杂度最大的路径是怎样的,这才是最终的时间复杂度.

因此上图的时间复杂度为O(n2)

函数调用

for (int i = 0; i < n; i++) {  //O(n)
             list.insert(0,i);   //O(n)
     }
复制代码

上面的insert语句的时间复杂度是O(n), 而不是O(1), 因此它的时间复杂度是O(n2).

函数调用要看函数体里面的时间复杂度.

注意:

  • 算法的速度并不能简单的以执行时间做为衡量标准

大O表示法

<<算法导论>>里的定义:

对于给定的函数g(n) , 用O(g(n))来表示如下函数的集合:

O(g(n)) = {f(n) : 存在正常量c和n0 , 使得对全部n>=n0 , 有0<=f(n)<=cg(n)}.

咱们使用O记号来给出函数的一个在常量因子内的上界.

大O表示法每每是表示最坏复杂度的.

常见排序算法及其对应的时间复杂度和空间复杂度

img

常见数据结构时间复杂度

image-20200623103802916

查找

  • 数组能够直接根据下标查询,因此是O(1)
  • 链表必须一个一个的去找,因此是O(n)

头部插入/删除

  • 数组须要把每一个数据都向后移动,因此是O(n)
  • 链表随意找一个位置放置元素,指针指向下一个便可,因此是O(1)

尾部插入/删除

  • 数组直接定位到尾部,输入数据就能够(数组未满才可插入)
  • 链表须要先遍历才能找到最后一个元素的位置,再进行插入

中间插入/删除

  • 数组的时间用在了数据的拷贝,覆盖上面

  • 链表的时间用在了遍历上面

数组和链表的选择

插入/删除不多,查询很是多,又不会 Out of memory ,采用数组.

若是是频繁的插入,遍历,查询检索不多,就采用链表.

相关文章
相关标签/搜索