美文网首页
数据结构算法简介

数据结构算法简介

作者: david161 | 来源:发表于2022-04-28 15:28 被阅读0次

在软件开发行业数据结构和算法是一个程序员的基本功,内功深厚的人后面学东西才会快。现实场景中的高并发、高扩展、海量数据的情况下也需要用到这些数据结构和算法知识。这些知识使我们对编程的精益求精非常有帮助。

什么是数据结构

数据结构(data structure)是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通俗的解释,数据结构描述了如何在内存中存数据。

常见的数据结构

image.png

什么是算法

算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。通俗的解释,算法就是一种解决特定问题的思路。
比如LRU算法,最近最少使用,解决的就是当空间不够用时,应该淘汰谁的问题,这是一种策略,不是唯一的答案,所以算法无对错,只有好和不好。


image.png

算法复杂度

数据结构和算法本质上是”快“和"省"。所以代码的执行效率是非常重要的度量,我们采用时间复杂度和空间复杂度来计算复杂度。

时间复杂度

大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(n2 )
时间复杂度也成为渐进时间复杂度。
计算时间复杂度的技巧
1)计算循环执行次数最多的代码
2)总复杂度=量级最大的复杂度
比如把上面两段代码合在一起

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( n2)
嵌套代码的复杂度等于嵌套内外代码复杂度的乘积(乘法法则)
常见的时间复杂度
1)O(1)
这种是最简单的,也是最好理解的,就是常量级
不是只执行了一行代码,只要代码的执行不随着数据规模(n)的增加而增加,就是常量级
在实际应用中,通常使用冗余字段存储来将O(n)变成O(1),比如Redis中有很多这样的操作用来提升访问性能
比如:SDS、字典、跳跃表等
2)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)
3)O(n)
这个前面已经讲了,很多线性表的操作都是O(n),这也是最常见的一个时间复杂度
比如:数组的插入删除、链表的遍历等
4)O(m+n)
代码的时间复杂度由两个数据的规模来决定,这个复制度本质上和O(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)
5)O(mn)*

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(mn),记作:O(mn)
当m==n时,为O( n2)

空间复杂度

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

相关文章

  • 数据结构和算法系列

    一、简介 1. 什么是数据结构和算法? 2. 为什么要学习数据结构和算法? 3. 如何学好数据结构和算法? 4. ...

  • 数据结构与算法 (Kotlin语言描述) / 陈光剑

    《数据结构与算法 (Kotlin语言描述)》/ 陈光剑 内容简介 本书主要介绍基本数据结构以及相关的经典算法,强调...

  • 数据结构算法简介

    在软件开发行业数据结构和算法是一个程序员的基本功,内功深厚的人后面学东西才会快。现实场景中的高并发、高扩展、海量数...

  • 思维导图之数据结构+算法

    数据结构+算法 = 程序 数据结构比较 参考文章 数据结构与算法数据结构与算法(java)

  • 数据结构与算法 - 时间复杂度

    目录 一、数据结构概要二、算法概要三、时间复杂度简介四、求解时间复杂度 一、数据结构 数据结构 是相互之间存...

  • 数据结构与算法 - 查找

    数据结构与算法系列文章数据结构与算法 - 时间复杂度数据结构与算法 - 线性表数据结构与算法 - 树形结构数据结构...

  • 数据结构与算法

    参考链接:算法 数据结构与算法 iOS数据结构 和 算法 上 算法 1、数据结构: 集合结构: 线性结构: 树形结...

  • 数据结构与算法 - 树形结构

    数据结构与算法系列文章数据结构与算法 - 时间复杂度数据结构与算法 - 线性表数据结构与算法 - 树形结构 目录 ...

  • 数据结构与算法-目录

    数据结构与算法-目录 C语言篇 数据结构和算法-C语言篇1-绪论数据结构和算法-C语言篇2-初识算法数据结构与算法...

  • 数据结构 - 跳表skiplist

    更多数据结构内容,请参考:数据结构 - 概要 简介 漫画算法:什么是跳跃表? Redis 为什么用跳表而不用平衡树...

网友评论

      本文标题:数据结构算法简介

      本文链接:https://www.haomeiwen.com/subject/ahncyrtx.html