通过js示例讲解时间复杂度与空间复杂度

1. 博客背景

今天有同事在检查代码的时候,由于函数写的性能不是很好,被打回去重构了,细思极恐,今天和大家分享一篇用js讲解的时间复杂度和空间复杂度的博客

2. 复杂度的表示方式

之前有看过的,你可能会看到这么一串东西

T(n) = O(f(n))
S(n) = O(f(n)) 

这个叫做大O表示法,其中的T代表的是算法需要执行的总时间

S表示的算法需要的总空间

f(n)表示的是代码执行的总次数

举个例子

function go(n) {
 var item = 0;   // 这里执行了一次
 for (var i = 0; i < n; i++) {  //这里执行了N次
  for (var j = 0; j < n; j++) {   //这里执行了n*n次
   item = item + i + j;   //这里执行了n*n次
  }
 }
 return item; //这里执行了一次
}

所以说上边这段代码是 1+n+n*n*2+1=2+n+2n²

也就是说 T(n) = O(f(2+n+2n²))

然后之前说了时间复杂度看的是一个代码执行的时间的趋势, 所以说在N,也就是规模比较大的时候,那些常量是起不到决定性的作用的,所以这个时候我们忽略这些常量,这里的例子是一个单段的代码,这里只看最大量级的循环就可以了

所以最后的这个代码的时间复杂度是T(n) = O(n²)

大家可以想想一下数据中平方的曲线图

3. 时间复杂度

3.1 时间复杂度的定义

首先什么是时间复杂度,时间复杂度这个定义如果在之前没有接触过的话,你可能会认为他代表的是一个代码执行的时间,其实不然,算法的时间复杂度就是说一个算法的执行时间根据数据规模增长的一个趋势,并不是说代码执行的具体时间

3.2 几种常见的时间复杂度

最简单的O(n)

for (var i = 0; i < n; i++) {
sum += i;
}

通俗易懂,这段代码的执行时间完全由N来控制,所以说T(n) = O(n)

当然还有个更简单的O(1)

function total(n) {

console.log(1)
}

无论怎么样,这段函数不受任何参数影响,代码走一遍就完事,这种的代码用T(n) = O(1) 表示

T(n) = O(n²)

上边的例子已经说了一个了两层循环的那种,在举一个时间复杂度多块代码的情况时间复杂度的计算方式

function go(i) {
 var sum = 0;
 for (var j = 0; j < i; j++) {
  sum += i;
 }
 return sum;
}
function main(n) {
 var res = 0;
 for (var i = 0; i < n; i++) {
  res = res + go(i); // 这里是重点
 }
}

在上边的代码种第二段代码里边调用了第一段代码,所以说在这个代码里边是

go:(1+n)

在main函数里边的时候是(1+n*go)=(1+n+n*n)

所以最后的时间复杂度是T(n) = O(n²)

3.3 多块代码的时间复杂度

上边距离说明的T(n) = O(n²) ,是一个函数在另一个函数里边被调用,这种情况是被把两个函数的时间复杂度相乘。

还有另外一种情况,就是说在一个函数里边有多块代码,但是并没有被相互调用,那么这种情况的时候,我们只需要取复杂度最大的代码块就可以了

比如说

    function go(n) {

     for (var i = 0; i < n; i++) {
      for (var j = 0; j < n; j++) {
       console.log(1)
      }
     }

     for (var i = 0; i < n; i++) {
      console.log(2)
     }
    }

上边这块代码中,第一块代码有两层循环,通过上边的例子我们已经得知复杂度是

下边这块代码,是n

那么在这种情况的时候,当N接近无限大的时候N是对n²起不到决定性作用的,所以上边这块代码的时间复杂度就是取最大值的n²

3.4 对数阶和相加情况

var i = 1;
while (i <= n) {
    i = i * 10;
}

在这段代码中,可以看到while里边,作为判断条件的i被每次*10,那么所以说最后循环的次数并不是n次,而是说十分之一n次,所以说这个时候的时间复杂度是10i=n,
i=logn

所以得出结论就是时间复杂度是T(n)=O(logn)

然后还有一种情况就是通过改变的变量去增加循环次数的,同理是增加了时间复杂度

还有一些其他的情况比如时间复杂度相加

function go(m,n) {

 for (var i = 0; i < n; i++) {
  console.log(1)
 }

 for (var i = 0; i < m; i++) {
  console.log(2)
 }

}

请看上边这一段,这段代码里边一个函数里边有两个循环,但是形参有两个,我们现在无法得知n和m到底谁大谁小,所以说这个时候代码的时间复杂度是O(m+n)

4. 空间复杂度

4.1 空间复杂度的定义

上边说了那么一大堆的时间复杂度,相比各位已经比较了解了,就名字来看,时间复杂度看的是代码的执行时间的趋势,那么同理的,空间复杂度就是指的占用内存的趋势

4.2 常见的空间复杂度

空间复杂度没有时间复杂度那么复杂,常见的就那么几种

毕竟我感觉不会有人一直循环着各种花样的声明变量吧。。。

如果有,那么请打死。。。。

  • O(1)
let a = 1;
let b = 1;
let c = 1;
let d = 1;

很简单,O(1)

  • O(n)
let arr =Array(n)

看这句代码,代码中创建了一个n长度的数组,很明显数组的长度根据n来决定,所以说
O(n)

这里需要说明一下,这里没有用循环,是因为只要不是在循环里边不停的声明变量,只改变值的话是不会层架空间复杂度的

  • O(n²)
let arr=[]
for (var i = 0; i < n; i++) {
  arr[i]=i
  for (var j = 0; j < n; j++) {
    arr[i][j]=j
  }
}

怎么样,猛的一看这个代码是不是很刺激,我觉得如果有这种情况的话,一般都会被乱棍打死了。。。

复杂度的优化

再说优化之前我先盗一张图给大家看一下各个复杂度的曲线图,方便大家有一个直观的认识

举个比较简单的优化的例子

console.time('a')
function go(n) {
   var item = 0;
   for (var i = 1; i <= n; i++) {
    item += i;
   }
   return item;
}
console.timeEnd('a')

console.time('b')
function go2(n) {
 var item = n*(n+1)/2
 return item;
}
console.timeEnd('b')

go(1000)
go2(1000)

大家可以打印一下看一下

希望大家原谅我数学不好,记得之前看到过一个等差数列的例子,想不到其他的性能优化的例子

希望大家看完之后可以了解这些概念,有的时候这个东西真的很重要,找一个曲线比较高的例子

斐波那契,就是从第三项开始依次等于前两项的和

斐波那契定义

function Fibonacci(n) {
  if (n <= 1 ) {
    return n;
  } else {
    return Fibonacci(n - 1) + Fibonacci(n - 2);
  }
}

console.time('b')
Fibonacci(????)
console.timeEnd('b')

有兴趣的可以试试打印一下,看看时间,不过大概50次的时候你得浏览器就应该没有响应了,具体请往上看曲线图。。。。

以上是我对时间复杂度和空间复杂度的一些认识,有不足或者不对的地方,希望指出来

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • 通过js示例讲解时间复杂度与空间复杂度

    1. 博客背景 今天有同事在检查代码的时候,由于函数写的性能不是很好,被打回去重构了,细思极恐,今天和大家分享一篇用js讲解的时间复杂度和空间复杂度的博客 2. 复杂度的表示方式 之前有看过的,你可能会看到这么一串东西 T(n) = O(f(n)) S(n) = O(f(n)) 这个叫做大O表示法,其中的T代表的是算法需要执行的总时间 S表示的算法需要的总空间 f(n)表示的是代码执行的总次数 举个例子 function go(n) { var item = 0; // 这里执行了一次 for

  • 原生js封装运动框架的示例讲解

    昨天我们说了一下原生JS中常用的兼容性写法,今天我们来说一下运动框架. 正常情况下我们要写一个运动的效果会用到tween.js这么一个插件,这个东西不是一般人写出来的,因为里面涉及的运动效果都是经过一堆数学的函数运算出来的,我们平常人是写不出来的,所有我们就自己封装一个运动框架,有什么问题改起来也方便,下面我们就开始封装. 首先,我们先写一个div,设置一些简单的样式,我们就拿这个div举例子 如下代码: #div{ width: 100px; height: 100px; background

  • js数字滑动时钟的简单实现(示例讲解)

    废话不多说,直接上代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> body,ul{margin:0;padding: 0;} .content{margin:100px auto;wid

  • 使用JS实现导航切换时高亮显示的示例讲解

    index.html代码内容 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>导航高亮显示</title> <style type="text/css"> body{ font-size:20px; } .nav{ list-style-type: none; margin:0; padding:0; } .cl

  • C语言 超详细讲解算法的时间复杂度和空间复杂度

    目录 1.前言 1.1 什么是数据结构? 1.2 什么是算法? 2.算法效率 2.1 如何衡量一个算法的好坏 2.2 算法的复杂度 2.3 复杂度在校招中的考察 3.时间复杂度 3.1 时间复杂度的概念 3.2 大O的渐进表示法 3.3 常见时间复杂度计算举例 4.空间复杂度 5. 常见复杂度对比 1.前言 1.1 什么是数据结构? 数据结构(Data Structure)是计算机存储.组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合. 1.2 什么是算法? 算法(Algorit

  • JS字符串分割方法整理汇总示例讲解(3种截取方法和6个辅助方法)

    目录 一.使用 slice() 截取 1,函数说明 2,使用样例 二.使用 substring() 截取 1.函数说明 2.使用样例 三.使用 substr() 截取 1.函数说明 2.使用样例 附:其他一些常用的方法 1.indexOf() 2,lastIndexOf() 3,split() 4,join() 5,concat() 6,charAt() JavaScript在开发中常常会需要截取字符串,而JS提供了slice() .substring().substr() 3种方法实现截取操作

  • Java 关于时间复杂度和空间复杂度的深度刨析

    目录 1.算法效率 2.时间复杂度 2.1时间复杂度的概念 2.2大O的渐进表示法 2.3常见时间复杂度计算 2.3.1常用的时间复杂度量级 2.3.2常见示例举例 2.3.2示例答案及分析 3.空间复杂度 1.算法效率 算法效率分析分为两种:第一种是时间效率,第二种是空间效率.时间效率被称为时间复杂度,而空间效率被称作空间复杂度. 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间 如今我们更关注的是时间复杂度,而对空间复杂度已不再关注. 2.时间复杂度 2

  • jquery实现用户登陆界面(示例讲解)

    实例如下所示: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <script src="js/jquery-1.8.0.min.js"></script> <script> var cnresu = false; $(function(){

  • PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)

    1.首先做主页面Ajax_pag.php 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Ajax做分页</title> <script src="bootstrap/js/jquery-1.11.2.min.js"></script> <script src="Ajax_

  • jq.ajax+php+mysql实现关键字模糊查询(示例讲解)

    对于这个功能企业上还算比较实用,推荐给大家: index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <style> *{margin:0;padding:0;} .text{width:200px;height:30px;line-height:30px;font-size:14px;outline:none;} ul{wid

随机推荐