算法的复杂度问题--------时间复杂度和空间复杂度

大O表示法:

  • 概念

如果一个问题的规模是n,解这一问题的某一算法所需要的时间为T(n),它是n的某一函数。T(n)称为这一算法的“时间复杂度”。当输入量n逐渐加大时,时间复杂度的极限情形称为算法的“渐近时间复杂度”。

`运行时间`指一种算法的运算时间的增速,并不是以秒为单位的速度。一个算法,并不仅仅要知道他运行的时间,还要知道其随着数据内容的增加他的运算时间是如何增加的。 O(n) 中n是操作的次数。

  • 表示意义

表示一种算法在最糟糕的情况下需要计算的次数。比如在一个电话簿(n个电话)中找一个电话,利用快速查找,最好的情况是第一次就找到,最坏的情况是第n次找到。这个运行时间要按照最糟糕的情况算  即O(n)。

我们常用大O表示法表示时间复杂度,注意它是某一个算法的时间复杂度。大O表示只是说有上界,由定义如果f(n)=O(n),那显然成立f(n)=O(n^2),它给你一个上界,但并不是上确界,但人们在表示的时候一般都习惯表示前者。此外,一个问题本身也有它的复杂度,如果某个算法的复杂度到达了这个问题复杂度的下界,那就称这样的算法是最佳算法。

  • 常见的大O运行时间(从快到慢进行排序)

    - O(㏒n)   对数时间  比如二分查找

    - O(n)      线性时间  比如简单查找

    - O(n*㏒n)      比如快速排序

    - O(n²)         比如选择排序

    - O(n!)         比如旅行者问题

复杂度与时间效率的关系:

c < log2n < n < n*log2n < n2 < n3 < 2n < 3n < n! (c是一个常量)

时间复杂度:

  • 通俗理解:执行这个算法需要花费的时间
  • 时间频度:一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了.并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多.一个算法中的语句执行次数称为语句频度或时间频度.记为T(n)。
  • 一般情况下,算法中的基本操作语句的重复执行次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n) / f(n) 的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作 T(n)=O( f(n) ),称O( f(n) )  为算法的渐进时间复杂度,简称时间复杂度。
  • T(n) 不同,但时间复杂度可能相同。 如:T(n)=n²+5n+6 与 T(n)=3n²+3n+2 它们的T(n) 不同,但时间复杂度相同,都为O(n²)。
  • 常见的时间复杂度有:常数阶O(1),对数阶O(log2n),线性阶O(n),线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3), k次方阶O(nk),指数阶O(2n)。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
  • 常见排序算法的时间复杂度
  最差时间分析 平均时间复杂度 空间复杂度
冒泡排序 O(n^{2}) O(n^{2}) O(1)
快速排序 O(n^{2}) O(n*log_2{n}) O(log_2{n})-O(n)
选择排序 O(n^{2}) O(n^{2}) O(1)
二叉树排序 O(n^{2}) O(n*log_2{n}) O(n)
插入排序 O(n^{2}) O(n^{2}) O(1)
堆排序 O(n*log_2{n}) O(n*log_2{n}) O(1)

空间复杂度:

  • 概念

一个算法在运行过程中临时占用存储空间大小的量度,记做 S(n)=O(f(n)) ,其中n为问题的规模。利用算法的空间复杂度,可以对算法的运行所需要的内存空间有个预先估计。

  • 一个算法执行时除了需要存储本身所使用的指令、常数、变量和输入数据外,还需要一些对数据进行操作的工作单元和存储一些计算所需的辅助空间。我们一般所讨论的是除正常占用内存开销外的辅助存储单元规模。
  • 算法执行时所需的存储空间包括以下两部分:

(1)固定部分。这部分空间的大小与输入/输出的数据的个数、数值无关。主要包括指令空间(即代码空间)、数据空间(常量、简单变量)等所占的空间。这部分属于静态空间。

(2)可变空间,这部分空间的主要包括动态分配的空间,以及递归栈所需的空间等。这部分的空间大小与算法有关。

  • 举例分析算法的空间复杂度:
public void reserse(int[] a, int[] b) {
    int n = a.length;
    for (int i = 0; i < n; i++) {
        b[i] = a[n - 1 - i];
    }
}

当程序调用 reserse() 方法时,要分配的内存空间包括:引用a、引用b、局部变量n、局部变量i

因此 f(n)=4 ,4为常量。所以该算法的空间复杂度 S(n)=O(1)

发布了16 篇原创文章 · 获赞 6 · 访问量 3302

猜你喜欢

转载自blog.csdn.net/weixin_42055771/article/details/82380444