算法复杂度介绍

数据结构和算法本质上是 " " 。所以代码的执行效率是非常重要的度量。
算法复杂度分为时间复杂度和空间复杂度。

时间复杂度

O复杂度表示法

int sum(int n){
    int s=0; //t
    int i=1; //t
    for(;i<=n;i++){ //t*n
        s=s+i; //t*n
    }
    return s; //t
}
n=100
1+1+100n+100n+1=200n+3
我们假设执行一行代码的时间为 t ,通过估算,代码的执行时间 T(n) 与执行次数成正比,记做 :
T(n)=O(f(n))
T(n) : 代码执行时间
n :数据规模
f(n) :每行代码执行次数总和
O :代码的执行时间与 f(n) 表达式成正比
上面的例子中的 T(n)=O(2n+2)
n 无限大时,低阶、常量、系统都可以忽略
所以 T(n)=O(n)
即上例中的时间复杂度为 O(n) ,也就是代码执行时间随着数据规模的增加而增长
int sum(int n){
    int s=0;
    int i=1;
    int j=1;
    for(;i<=n;i++){// n
        j=1;
        for(;j<=n;j++){ //n*n
            s=s+i+j; //n*n
        }
    }
    return s;
}
上例中 T(n)=O(n*n) ,也就是代码执行时间随着数据规模的增加而平方增长
即:上例中的时间复杂度为 O(n² )
时间复杂度也成为 渐进时间复杂度

计算时间复杂度的技巧

  • 计算循环执行次数最多的代码
  • 总复杂度=量级最大的复杂度
比如把上面两段代码合在一起
int sum(int n){
    int s=0;
    int i=1;
    int j=1;
    for(;i<=n;i++){ //t*n
        s=s+i; //t*n
    }
    for(;i<=n;i++){// n
        j=1;
        for(;j<=m;j++){ //n*m
            s=s+i+j; //n*m
        }
    }
    return s;
}
时间复杂度为 O(n²)
  • 嵌套代码的复杂度等于嵌套内外代码复杂度的乘积(乘法法则)

常见的时间复杂度

O(1)
这种是最简单的,也是最好理解的,就是常量级
不是只执行了一行代码,只要代码的执行不随着数据规模 (n) 的增加而增加,就是常量级
在实际应用中,通常使用冗余字段存储来将 O(n) 变成 O(1) ,比如 Redis 中有很多这样的操作用来提
升访问性能
比如 :SDS 、字典、跳跃表等
O(logn)O(nlogn)
i = 1;
while(i <= n){
    i = i * 2;// 执行最多
}
2 =n
x=log n
忽略系数为 logn
T(n)=O(logn
如果将该代码执行 n
则时间复杂度记录为 :T(n)=O(n*logn ),即 O(nlogn)
快速排序、归并排序的时间复杂度都是 O(nlogn)
O(n)
很多线性表的操作都是 O(n), 这也是最常见的一个时间复杂度
比如:数组的插入删除、链表的遍历等
O(m+n)
代码的时间复杂度由两个数据的规模来决定
int sum(int m,int n){
    int s1=0;
    int s2=0;
    int i=1;
    int j=1;
    for(;i<=m;i++){
        s1=s1+i; // 执行最多
    }
    for(;j<=n;j++){
        s2=s2+j; //执行最多
    }
    return s1+s2;
}
m n 是代码的两个数据规模,而且不能确定谁更大,此时代码的复杂度为两段时间复杂度之和,
T(n)=O(m+n) ,记作: O(m+n)
O(m*n)
int sum(int m,int n){
    int s=0;
    int i=1;
    int j=1;
    for(;i<=m;i++){// m
        j=1;
        for(;j<=n;j++){ //m*n
            s=s+i+j; //m*n
        }
    }
    return s;
}
根据乘法法则代码的复杂度为两段时间复杂度之积,即
T(n)=O(m*n) ,记作: O(m*n)
m==n , O(n²)

空间复杂度

空间复杂度全称是渐进空间复杂度,表示算法的存储空间与数据规模之间的增长关系
比如将一个数组拷贝到另一个数组中,就是相当于空间扩大了一倍 :T(n)=O(2n) ,忽略系数。即为:
O(n) ,这是一个非常常见的空间复杂度,比如跳跃表、 hashmap 的扩容
此外还有 :O(1) ,比如原地排序、 O(n ) 此种占用空间过大
由于现在硬件相对比较便宜,所以在开发中常常会利用空间来换时间,比如缓存技术
典型的数据结构中空间换时间是:跳跃表
在实际开发中我们也更关注代码的时间复杂度,而用于执行效率的提升
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值