一、引言
这次分享的主要目的是和大家一起再回顾一下数据结构的知识,如果能给大家的实际开发工作带来一些小的启发就更棒了~~
这次分享的主要内容如下图所示:
我们会从数据本身的逻辑结构讲起,再到其逻辑结构在计算机中的存储形式,再到数据的基本操作,最后到一些常见的算法。
这条链路反过来就是,我们在写程序时常用的算法,这些算法通过数据结构的一些基本操作来操作数据及其在计算机中存储。
二、数据的逻辑结构和物理结构
那接下来我们进入第一部分的内容,数据的逻辑结构和物理结构。那什么是逻辑结构呢,有小伙伴还记得逻辑结构的定义吗?
逻辑结构:是指数据对象中数据元素之间的相互关系。
Emmmm,咋一看逻辑结构的概念可能比较抽象,让我们继续往下看逻辑结构的分类大家就秒懂了~~
逻辑结构分为以下四种:
- 集合结构:集合结构中的数据元素除了同属于一个集合外,它们之间没有其他关系。
- 线性结构:线性结构中的数据元素之间是一对一的关系。
- 树形结构:树形结构中的数据元素之间存在一种一对多的层次关系。
- 图形结构:图形结构的数据元素是多对多的关系。
总结来说,逻辑结构是针对具体问题的,是为了解决某个问题,在对问题理解的基础上,选择一个合适的数据结构表示数据元素之间的逻辑关系。
看完逻辑结构接下来让我们一起来看看数据的物理结构(也就是存储结构)。
物理结构:是指数据的逻辑结构在计算机中的存储形式。
物理结构分为以下两种:
- 顺序存储结构:把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。
- 链式存储结构:把数据元素存放在任意存储单元内,这组存储单元可以是连续的也可以是不连续的。因为数据的存储关系不能反映其逻辑关系,因此需要一个指针存放数据元素的地址,这样就可以通过地址找到相关联数据元素的位置。
了解完数据的逻辑结构和物理结构,现在我们可以得到数据结构的概念了~~
数据结构:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
emmmm,到这里到家有什么疑问么?没有的话我们就继续往下介绍常见的数据结构及其基本操作了~~
三、常见的数据结构及其基本操作
数据结构 | 图示 | 基本操作 | 特点 | 常用场景 |
---|---|---|---|---|
数组 | 增、删、插入:O(N), 查:O(1) | 1)存储上:连续存储,可以随机访问; 2)空间利用上:相对节约存储空间; 3)内存分配上:内存空间必须⼀次性分配够; 4)扩容:需要重新分配⼀块更⼤的空间, 时间复杂度 O(N) | 数据比较少;经常做的运算是按序号访问数据元素; | |
链表 | 增、删、插入:O(1), 查:O(N) | 1)存储上:存储空间不连续,不支持随机访问; 2)空间利用上:会消耗相对更多的储存空间; 3)内存分配上:利用离散的内存空间; 4)扩容:不存在扩容问题, 时间复杂度 O(1) | 对线性表的长度或者规模难以估计;频繁做插入删除操作;构建动态性比较强的线性表。 | |
栈 | 出栈、入栈:O(1) | 1)数组实现:元素的变化范围可控; 2)链表实现:元素的变化范围不可控 | 递归:例如chrome调试的调用栈; 逆波兰式:例如求解四则运算 | |
队列 | 出队:入队:O(1) | 1)数组实现:确定队列长度的最大值时,使用循环队列; 2)链表实现:无法预估队列的长度时,使用链队列 | 键盘输入循环缓冲区问题 | |
树 | 树的4种遍历:前序、中序、后序、层级 | 存储结构:1)双亲表示法; 2)孩子表示法; 3)孩子兄弟表示法 | 有序二叉树查找; 哈夫曼编码; react fiber的实现 | |
图 | 图的遍历 | 存储结构:1)邻接矩阵:边集用数组表示; 2)邻接表:边集用链表表示; 3)十字链表:针对有向图邻接表的优化; 4)邻接多重表:针对无向图邻接表结构优化; 5)边集数组:更多的是对边的关注 | 深度优先算法; 广度优先算法 |
算法 | 时间复杂度 | 基础框架 | 应用场景 |
---|---|---|---|
二分查找 | O(logn) | 只能查找顺序存储的数据集,即数组; 针对的是静态有序数据集; 不适合数据量太大或者太小的场景 | |
选择排序 | O(n2) | n比较小且不要求排序的稳定性时 | |
树的遍历 | O(n) | 哈夫曼编码; linux中文件系统的目录结构; 路由协议; linux中进程的调度 | |
深度优先 | O(n) | 回溯算法 | |
广度优先 | O(n) | 树的层序遍历; 最短路径 |
O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
五、总结
最后和大家分享一下两个书中作者的学习数据结构和算法技巧:
- 数据结构:把图学透了基本等于理解了数据结构这门课的精神。
- 算法:分析问题,⼀定要有递归的思想,⾃顶向下,从抽象到具体。labuladong的作者以这样的思维分析归纳了各种算法的框架,刷起leetcode得心应手。
emmmm,到这里我们今天的分享就结束啦~~~感谢大家!!
六、参考资料
- 《大话数据结构》
- 《labuladong算法小抄》