• 时间复杂度与空间复杂度


    18年互联网寒冬,特别是游戏行业,版号一年没发。待经济春暖花开之时,也让自己在行业行业中增加竞争力。

    为什么要进行复杂度分析?
    1.和性能测试相比, 复杂度分析有不依赖执行环境、 成本低、 效率高、 易操作、 指导性强的特点。
    2.掌握复杂度分析, 将能编写出性能更优的代码, 有利于降低系统开发和维护成本。

    时间复杂度:时间复杂度是衡量一个算法重要的指标之一,当数据量越大,算法的效率也就越能体现出来,以时间复杂度为例, 由于时间复杂度描述的是算法执行时间与数据规模的增长变化趋势, 所以常量阶、 低阶以及系数实际上对这种增长趋势不产决定性影响, 所以在做时间复杂度分析时忽略这些项。

    时间负责度特点如下:

    • 只关注循环执行最多的一段代码
    • 加法原则,总复杂度等于量级最大的复杂度
    • 嵌套代码的复杂度等于嵌套内代码复杂度的乘积

    俗称:

      1) 单段代码看高频: 比如循环。
      2) 多段代码取最大: 比如一段代码中有单循环和多重循环, 那么取多重循环的复杂度。
      3) 嵌套代码求乘积: 比如递归、 多重循环等
      4) 多个规模求加法: 比如方法有两个参数控制两个循环的次数, 那么这时就取二者复杂度相加。
    常用的复杂度级别:
      多项式阶: 随着数据规模的增长, 算法的执行时间和空间占用, 按照多项式的比例增长。 包括,O(1)(常数阶) 、 O(logn)(对数阶) 、 O(n)(线性阶) 、 O(nlogn)(线性对数阶) 、 O(n^2)(平方阶) 、 O(n^3)(立方阶)。
      非多项式阶: 随着数据规模的增长, 算法的执行时间和空间占用暴增, 这类算法性能极差。 包括,O(2^n)(指数阶) 、 O(n!)(阶乘阶) 。

    最好、平均、最坏、均摊时间复杂度:

      

     1 // n 表示数组 array 的长度
     2 int find(int[] array, int n, int x) {
     3   int i = 0;
     4   int pos = -1;
     5   for (; i < n; ++i) {
     6     if (array[i] == x) {
     7       pos = i;
     8       break;
     9     }
    10   }
    11   return pos;
    12 }

      这段代码中假如寻找的这个数据正好在数组中下标为0的位置,时间复杂度为O(1),也就是最好时间复杂度。假如这个数据中没有这个数据,需要把整个数组遍历一遍,

    时间复杂度为O(n)也就是最坏的时间复杂度。

      考虑到这两种情况都比较极端,假设要查找的这个数据在数组中和不在数组中的的概率都为1/2,要查找的数据出现在数组0~n-1中的概率也是一样的为1/n,根据概率的乘法

    原则,要查找的数据出现在0~n-1中的概率为1/2n。如果我们把每种情况发生的概率也算进入,平均时间复杂度的公式就变成这样了:

    这个值就是概率论中的加权平均值,去掉常亮和系数的结果就是O(n)所以平均时间复杂度也为O(n)。

    均摊时间复杂度:

     1 // array 表示一个长度为 n 的数组
     2 // 代码中的 array.length 就等于 n
     3 int[] array = new int[n];
     4 int count = 0;
     5 void insert(int val) {
     6 if (count == array.length) {
     7     int sum = 0;
     8     for (int i = 0; i < array.length; ++i) {
     9       sum = sum + array[i];
    10    } 
    11   array[0] = sum;
    12   count = 1;
    13 }
    14    array[count] = val;
    15   ++count;
    16 }    

    这个算法在比较在绝大部分情况下时间复杂度都是0(1),只有在某种极端的情况下时间复杂度才是O(n),第二个不同之处在于一都是经过一个O(n)的插入之后在经过n-1个0(1)的插入,循环往复。所以可以把耗时最多一次操作,均摊到n-1个操作中,经过均摊后,这个算法的时间复杂度就是O(1)。这就是比较少见的情况下的均摊时间复杂度。

    空间复杂度:

      算法的指标中空间复杂度也是一个重要的指标。空间复杂度的全称是渐进空间复杂度,表示算法的存储空间与数据规模之间的增长关系。

      我们常见的空间复杂度就是 O(1)O(n)O(n ), 像 O(logn)O(nlogn) 这样的对数阶复杂度平时很少用。

  • 相关阅读:
    Redis详解(一)- redis的简介与安装
    集合-全部集合概览
    集合-LinkedList源码解析
    集合-ArrayDeque源码解析
    集合-DelayQueue源码解析
    集合-ConcurrentLinkedQueue 源码解析
    集合-LinkedTransferQueue源码解析
    集合-PriorityBlockingQueue 源码解析
    集合-SynchronousQueue 源码解析
    集合-LinkedBlockingQueue 源码解析
  • 原文地址:https://www.cnblogs.com/huangzhenxiong/p/10117081.html
Copyright © 2020-2023  润新知