前端 算法的时间复杂度和空间复杂度

算法的评估

对于一个问题,经常有多种不同的求解算法,这时候我们就需要一个对算法进行评估的标准,找出最优的方案,评估一个算法有以下几个维度:

  • 正确性:能正确的实现功能,满足问题的需求。
  • 易读性:通常,写出一个利与人类阅读的代码和利于机器阅读的代码一样重要
  • 健壮性:对于预料之外的输入,也能做出合适的处理。
  • 时空性:算法的时间性能(算法的计算量)和空间性能(算法需要的存储量)、

时间复杂度

时间复杂度的计算方法

时间复杂度:在给定输入(问题规模)下,算法的计算量。

所以说,求一个算法的时间复杂度,就是求这个算法在给定问题规模下的计算量,那么问题来了:如何求算法的计算量?

算法计算量的求法规则如下:

  • 1、在算法中选择几种“基本操作”,例如:赋值语句、数学运算语句等等。
  • 2、给定输入下,计算算法执行了多少次“基本操作”。
  • 3、“基本操作”的次数即可作为计算量。
实例与大O表示法

我们以一个例子来说明,求如下表达式的值:

// 阶乘的和
1! + 2! + 3! + ... + n!

我们可以写出如下程序(js代码):

function factorial (n) {
    var s = 0,
        temp = 1
    for (var i = 1; i <= n; i++) {
        temp = 1
        for (var j = 1; j <= i; j++) {
            temp *= j
        }
        s += temp
    }
    return s
}

我们根据之前总结的算法计算量的求法规则可知,求解一个算法的计算量分为三个步骤,第一步:确定基本操作,对于上面的代码我们所挑选的基本操作如下:

  • 第一部分赋值语句:

    var s = 0
      temp = 1
    

当我们的输入规模即 n 变化时,这两条语句的执行次数没有变,始终是 2 次。

  • 第二部分赋值语句:

    for (var i = 1; i <= n; i++) {
          temp = 1
          ...
    }
    

    第一层循环里的 temp = 1,该语句的执行次数等于输入规模 n

  • 乘法计算语句:
for (var j = 1; j <= i; j++) {
    temp *= j
}

第二层循环里的 temp *= j,该语句的执行次数,当 n = 1 时执行 1 次,当 n = 2 时执行 1 + 2 次,当 n = 3 时执行 1 + 2 + 3 次,所以该语句的执行次数与输入规模 n 的关系是 1 + 2 + 3 + ... + n = n(n + 1) / 2

  • 加法计算语句:

    for (var i = 1; i <= n; i++) {
      ...
      s += temp
    }
    

    第一层循环里的加法赋值语句,该语句的执行次数等于输入规模 n

综上所述,根据我们选择的“基本操作”,可以计算出该算法的基本操作次数与输入规模 n 的关系如下:

T(n) = 2 + n + n(n + 1) / 2 + n = 1/2n^2 + 3/2n + 2

当 n 足够大时,n^2 起支配作用,使用 O(n^2) 表示 T(n) 的近似值,这种表示法成为 大 O 表示法

常见的时间复杂度阶数
  • 常熟阶 O(1):即算法的计算量不随着输入规模的变化而变化。
  • 线性阶 O(n)
  • 多项式阶 O(n^c):常见的多项式阶如 O(n^2)、O(n^3)
  • 指数阶 O(C^n):常见的指数阶如 O(2^n)

一般我们认为一个算法的时间复杂度为指数阶的时候,该算法是实际不可运算的,大家可以想象一下,如果一个算法的时间复杂度为 O(2^n) 当 n = 1000 时,这个数值是何等恐怖。更何况我们的输入规模 n 很可能远大于 1000。

另外我们认为时间复杂度为 O(n)O(log2N)O(n^2) 是高效的算法。对于合理大的 nO(n^3) 也是可以接受的。

空间复杂度

空间复杂度的计算方法

空间复杂度:给定输入(问题规模)下,算法运行时所占用的临时存储空间。

一个算法执行期间所占用的存储量分为三部分:

  • 算法本身的代码所占用的空间
  • 输入数据所占用的空间
  • 辅助变量所占用的空间

由于实现不同算法所需的代码不会有数量级的差别,所以算法本身代码所占用的空间我们可以不考虑

输入的数据所占用的空间是由问题决定的,与算法无关,所以我们也不需要考虑

我们需要考虑的只有一个:程序执行期间,辅助变量所占用的空间。

计算方法类似于计算算法的时间复杂度,空间复杂度我们用 S(n) 来表示,它同样是输入数据规模 n 的函数,用大 O 表示法记为:

S(n) = O(g(n))

其中 g(n) 是一个关于 n 的函数,如:g(n) = ng(n) = n^2g(n) = log2N 等等。

实例

假设我们有一个数组,该数组有100个元素,写一个转置该数组的算法:

function reverse (arr) {
    for (var i = 0; i <= arr.length / 2 - 1; i++) {
        var temp = arr[i]
        arr[i] = arr[arr.length - i - 1]
        arr[arr.length - i - 1] = temp
    }
}

上面的算法中,我们采用中间变量 temp 对数组的值进行逐个对应的首尾交换,最终达到转置的目的,我们可以看到,辅助变量只有一个即 temp,该变量存储一个数字类型的值,temp 所占用的内存不会随输入数组规模的增大而增大,所以上面算法的控件复杂度为 O(1),是常数阶,即上面算法的空间复杂度 S(n) = O(1)

from: http://blog.poetries.top/js-knowledge-note/#/note/algorithm/time-space

原文地址:https://www.cnblogs.com/GarfieldEr007/p/12251700.html

时间: 2024-10-11 17:34:45

前端 算法的时间复杂度和空间复杂度的相关文章

算法的时间复杂度和空间复杂度

<算法的时间复杂度和空间复杂度合称为算法的复杂度> --->算法的时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了.并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多.一个算法中的语句执行次数称为语句频度或时间频度.记为T(n). (2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模

[算法技术]算法的时间复杂度与空间复杂度

1.时间复杂度 算法的时间复杂度是衡量一个算法效率的基本方法.在阅读其他算法教程书的时候,对于算法的时间复杂度的讲解不免有些生涩,难以理解.进而无法在实际应用中很好的对算法进行衡量.            <大话数据结构>一书在一开始也针对算法的时间复杂度进行了说明.这里的讲解就非常明确,言简意赅,很容易理解.下面通过<大话数据结构>阅读笔记的方式,通过原因该书的一些简单的例子和说明来解释一下算法的时间复杂度和它的计算方法.          首先从基本定义下手,来了解一下什么是“

算法的时间复杂度和空间复杂度合称为算法的复杂度

算法的时间复杂度和空间复杂度合称为算法的复杂度. 1.时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了.并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多.一个算法中的语句执行次数称为语句频度或时间频度.记为T(n). (2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时

【计算机基础】 常用的排序算法的时间复杂度和空间复杂度

常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n) 选择排序 O(n2) O(n2) 稳定 O(1) 二叉树排序 O(n2) O(n*log2n) 不一顶 O(n) 插入排序 O(n2) O(n2) 稳定 O(1) 堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1) 希尔排序 O O 不稳定 O(1) 1

算法的时间复杂度和空间复杂度-总结

算法的时间复杂度和空间复杂度-总结 通常,对于一个给定的算法,我们要做 两项分析.第一是从数学上证明算法的正确性,这一步主要用到形式化证明的方法及相关推理模式,如循环不变式.数学归纳法等.而在证明算法是正确的基础上,第二部就是分析算法的时间复杂度.算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好反映出算法的优劣与否.因此,作为程序员,掌握基本的算法时间复杂度分析方法是很有必要的.       算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量

算法的时间复杂度和空间复杂度详解

通常,对于一个给定的算法,我们要做 两项分析.第一是从数学上证明算法的正确性,这一步主要用到形式化证明的方法及相关推理模式,如循环不变式.数学归纳法等.而在证明算法是正确的基础上,第二部就是分析算法的时间复杂度.算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好反映出算法的优劣与否.因此,作为程序员,掌握基本的算法时间复杂度分析方法是很有必要的.       算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量.而度量一个程序的执行时间通常有两种

C#中常用的排序算法的时间复杂度和空间复杂度

常用的排序算法的时间复杂度和空间复杂度 常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n) 选择排序 O(n2) O(n2) 稳定 O(1) 二叉树排序 O(n2) O(n*log2n) 不一顶 O(n) 插入排序 O(n2) O(n2) 稳定 O(1) 堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1)

转 算法的时间复杂度和空间复杂度-总结

http://blog.csdn.net/zolalad/article/details/11848739 通常,对于一个给定的算法,我们要做 两项分析.第一是从数学上证明算法的正确性,这一步主要用到形式化证明的方法及相关推理模式,如循环不变式.数学归纳法等.而在证明算法是正确的基础上,第二部就是分析算法的时间复杂度.算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好反映出算法的优劣与否.因此,作为程序员,掌握基本的算法时间复杂度分析方法是很有必要的.      

常用的排序、查找算法的时间复杂度和空间复杂度

常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 插入排序 O(n2) O(n2) 稳定 O(1) 选择排序 O(n2) O(n2) 稳定 O(1) 二叉树排序 O(n2) O(n*log2n) 不一顶 O(n) 快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n) 堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1) 希尔排序 O O 不稳定 O(1) 查