时间复杂度/空间复杂度

时间复杂度、空间复杂度我之前从来没有了解过,他们是什么,有什么作用呢?? 最近偶然的机会看算法遇到了这两个东西,所以就简单的来了解一下,以下纯属个人理解,有问题欢迎指出~~

那么什么是时间复杂度,什么是空间复杂度呢??

  • 时间复杂度:一个算法的执行时间根据数据规模增加的一个趋势。
  • 空间复杂度:占用内存的趋势。

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

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

这个叫做大O表示法,表示随着输入的值变化,程序运行所需要的时间与输入值的变化关系。

T表示算法需要执行的总时间

S表示算法需要的总空间

fn表示代码执行的总次数

时间复杂度空间复杂度对于我们的工作有什么帮助呢??

  • 对于不同的数据规模,能够决策采用不同的解决方案。
  • 了解什么情况下用暴力解法就能够解决问题,避免写复杂的代码。
  • 在写代码之前,就能够预估程序的运行时间,从而可以知道是否能够满足产品需求。
  • 在程序出现性能瓶颈时,能够有解决方案而不是抓瞎。

时间复杂度,空间复杂度是怎么计算的??

通过代码能够更好的来了解:

function go(n) {
    var item = 0; // 执行1次
    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次
}

// 所以以上的T(n) = O(f(1+n+n*n*2+1))) = O(f(2+n+2n²)))

/*
时间复杂度看的是代码执行时间的一个趋势,所以说在于n,当数据量特别大的时候,那些常量起不到决定性的作用,常常被忽略掉。这里只看大量级的循环就行,所以这个代码的时间复杂度为:T(n) = O(n²)
*/

几种常见的时间复杂度:

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

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

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

function total() {
    console.log(1);
}

在下面的代码种第二段代码里边调用了第一段代码,所以说在这个代码里边是 go: (1+n)

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

所以最后的时间复杂度是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); // 这里是重点
  }
}

还有另外一种情况,就是说在一个函数里边有多块代码,但是并没有被相互调用,那么这种情况的时候,我们只需要取复杂度最大的代码块就可以了下边这块代码中,第一块代码有两层循环,通过上边的例子我们已经得知复杂度是n²+n。

那么在这种情况的时候,当N接近无限大的时候N是对n²起不到决定性作用的,所以下边这块代码的时间复杂度就是取最大值的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)
    }
}

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

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

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

function go(m,n) {
    for (var i = 0; i < n; i++) {
        console.log(1)
    }
    for (var i = 0; i < m; i++) {
        console.log(2)
    }
}

 

空间复杂度和时间复杂度差不多,几种常见的空间复杂度有:

O(1)

let a = 1;
let b = 1;
let c = 1;

O(n)

/*
代码中创建了一个n长度的数组,很明显数组的长度根据n来决定,所以空间复杂度为n
这里没有用循环,是因为只要不是在循环里边不停的声明变量,只改变值的话是不会层架空间复杂度的
*/

let arr = Array(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;
    }
}

几种排序的时间复杂度和空间复杂度

排序类型

时间复杂度

空间复杂度

是否稳定

冒泡排序

最好O(n)

最坏O(n²)

平均O(n²)

O(1)

快速排序

最好O(nlogn)

最坏O(n2)

平均O(nlogn)

最好O(logn)

最差O(n)

插入排序

最好O(n)

最坏O(n²)

平均O(n²)

O(1)

希尔排序

最好O(nlog²n)

最坏O(nlog²n)

平均O(nlogn)

O(1)

选择排序

O(n²)

O(1)

否,因为会遇到重复的值

归并排序

最好O(nlogn)

最坏O(nlogn)

平均O(nlogn)

O(n)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值