1 数组

数组应该是最简单的数据结构了,所谓数组,便是可以在内存中连续存储多个元素的结构。需要注意,数组在内存中的分配是连续的,其中的元素通过数组下标进行访问且下标以0开始。

数组的优点如下:

  1. 结构简单
  2. 可在常数时间内访问数组元素

数组的缺点如下:

  1. 数组长度在定义数组时便已固定,不可修改,无法扩容
  2. 数组只能存储一种类型的数据
  3. 添加,删除操作耗时长

2 链表

链表是最简单的动态数据结构。链表是物理存储单元上非连续的、非顺序的存储结构,每个元素包含两个结点,一个是存储元素的数据域,另一个是指针域。根据指针域中指针的指向,我们可以把链表细分为单向链表、双向链表以及循环链表。

链表的优点如下:

  1. 动态数据结构,不需考虑容量问题
  2. 添加,删除操作较快

链表的缺点如下:

  1. 与数组相比,不可随机访问,访问单个元素开销较大
  2. 链表中的额外指针引用需要浪费内存

2.1 单向链表

单向链表是最简单的链表形式,我们将链表中最基本的数据称为节点,那么每一个节点包含了数据块和指向下一个节点的指针。

2.2 双向链表

所谓双向,便是指有两个方向。与单向链表不同,双向链表的每一个节点不仅存储指向下一个节点的指针,而且存储指向前一个节点的指针。

2.3 循环链表

顾名思义,循环链表会达到“循环”的效果,即首尾相连。其具体实现方式为在链表的尾部增加一个指向头结点的指针,头结点也增加一个指向尾节点的指针。

3 栈

栈是限定仅在表尾(栈顶 top)进行插入和删除操作的后进先出的线性表。入栈指从栈顶放入元素,而出栈指从栈顶取出元素。

4 队列

队列是一种先进先出的线性表,简称FIFO(First In First Out)。队列是一种只允许在一端进行插入操作,而在另一端进行删除操作的线性表。允许插入的一端被称为队尾,允许删除的一端被称为队头。

5 树

树是由结点或顶点和边组成的(可能是非线性的)且不存在着任何环的一种数据结构。没有结点的树称为空树,一棵非空的树包括一个根结点,还可能有多个附加结点,所有结点构成一个多级分层结构。

以下内容参考:常用数据结构——树

5.1 二叉树

每个结点至多拥有两棵子树(二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。

其性质如下:

  1. 若二叉树的层次从 0 开始,则在二叉树的第 i 层至多有 2^i 个结点(i>=0)
  2. 高度为 k 的二叉树最多有 2^(k+1) - 1 个结点 (k>=-1) (空树的高度为 -1)
  3. 对任何一棵二叉树,如果其叶子结点(度为 0)数为 m, 度为 2 的结点数为 n, 则 m = n + 1

二叉树的遍历方法有以下三种:

  1. 中序遍历:即左-根-右遍历,对于给定的二叉树根,寻找其左子树;对于其左子树的根,再去寻找其左子树;递归遍历,直到寻找最左边的节点 i,其必然为叶子,然后遍历 i 的父节点,再遍历i的兄弟节点。随着递归的逐渐出栈,最终完成遍历
  2. 先序遍历:即根-左-右遍历
  3. 后序遍历:即左-右-根遍历

其中二叉树又分为以下三种:完美二叉树,完全二叉树,完满二叉树

5.1.1 完美二叉树(满二叉树)

除了叶子节点之外的每一个节点都有两个孩子,每一层(包括最后一层)都被完全填充。

5.1.2 完全二叉树

除了最后一层之外的其他每一层都被完全填充,并且所有节点都保持向左对齐。

5.1.3 完满二叉树

除了叶子节点之外的每一个节点都有两个孩子节点。

5.2 二叉查找树

二叉查找树也称为有序二叉查找树,其性质如下:

  1. 任意节点如果左子树不为空,则左子树的值均小于根节点的值
  2. 任意节点如果右子树不为空,则右子树的值均大于根节点的值
  3. 任意节点的左右子树也分别是二叉查找树
  4. 没有键值相等的节点

二叉查找树具有一定的局限性,在某些情况下,二叉查找树会退化成一个线性链。

5.3 AVL 树

AVL 树是带有平衡条件的二叉查找树,和红黑树相比,它是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1)。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的。

AVL 树特点如下:

  1. AVL 树是一棵二叉搜索树
  2. AVL 树的左右子节点也是 AVL 树
  3. 每个节点的左右子节点的高度之差的绝对值最多为1,即平衡因子为范围为[-1,1]

AVL 树适合用于插入删除次数比较少,但查找多的情况。

5.4 红黑树

红黑树是一种自平衡二叉查找树,通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保从根到叶子节点的最长路径不会是最短路径的两倍,用非严格的平衡来换取增删节点时候旋转次数的降低,任何不平衡都会在三次旋转之内解决。

红黑树的性质如下:

  1. 节点是红色或黑色
  2. 根节点是黑色
  3. 每个叶子节点都是黑色的空节点
  4. 每个红色节点的两个子节点都是黑色(从每个叶子到根的所有路径上不能有两个连续的红色节点)
  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点

至于红黑树与 AVL 树的比较,红黑树的查询性能略微逊色于 AVL 树,因为比 AVL 树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的 AVL 树最多多一次比较,但是,红黑树在插入和删除上大优于 AVL 树,AVL 树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所做的红黑变换和旋转的开销,相较于 AVL 树为了维持平衡的开销要小得多。

红黑树使用场景如下:

  1. 广泛用在 C++ 的 STL 中,map 和 set 都是用红黑树实现的
  2. 著名的 linux 进程调度 Completely Fair Scheduler 是用红黑树管理进程控制块的
  3. epoll 在内核中的实现,用红黑树管理事件块
  4. 在 nginx 中,用红黑树管理 timer

5.5 B 树

B_TREE 是一种平衡多路查找树,是一种动态查找效率很高的树形结构。B_TREE 中所有结点的孩子结点的最大值称为 B_TREE 的阶,B_TREE 的阶通常用 m 表示,简称为 m 叉树。一般来说,应该是 m>=3。一颗 m 阶的 B_TREE 或是一颗空树,或者是满足下列条件的 m 叉树:

  1. 树中每个结点最多有 m 个孩子结点
  2. 若根结点不是叶子节点,则根结点至少有2个孩子结点
  3. 除根结点外,其它结点至少有( m/2 的上界)个孩子结点
  4. 结点的结构如下图所示,其中,n 为结点中关键字个数,(m/2 的上界)-1 <= n <= m-1;di(1<= i <= n)为该结点的 n 个关键字值的第 i 个,且di < d(i+1);ci(0<= i <=n)为该结点孩子结点的指针,且 ci 所指向的节点的关键字均大于或等于 di 且小于 d(i+1)
  5. 所有的叶结点都在同一层上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)

B 树为大块数据的读写操作做了优化,同时它也可以用来描述外部存储。(支持对保存在磁盘或者网络上的符号表进行外部查找)

B_TREE 的查找类似二叉排序树的查找,所不同的是 B-树每个结点上是多关键码的有序表,在到达某个结点时,先在有序表中查找,若找到,则查找成功;否则,到按照对应的指针信息指向的子树中去查找,当到达叶子结点时,则说明树中没有对应的关键码。由于 B_TREE 的高检索效率,B-树主要应用在文件系统和数据库中,对于存储在硬盘上的大型数据库文件,可以极大程度减少访问硬盘次数,大幅度提高数据检索效率。

无论二叉搜索树还是 AVL 树,当数据量比较大时,都会由于树的深度过大而造成 I/O 读写过于频繁,进而导致查询效率低下,因此对于索引而言,多叉树结构成为不二选择。特别地,B-Tree 的各种操作能使 B 树保持较低的高度,从而保证高效的查找效率。

5.6 B+ 树

B+ 树是 B 树的变体,也是一种多路搜索树。B+ 树的非叶子结点相当于是叶子结点的索引,叶子结点相当于是存储(关键字)数据的数据层。B+Tree 是应文件系统所需而产生的一种 B_TREE 树的变形树。一棵 m 阶的 B+ 树和 m 阶的 B_TREE 的差异主要在于:B+ 树只有到达叶子结点才会命中,而 B 树可以在非叶子结点命中。

下图为一棵3阶的 B+ 树。通常在 B+ 树上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点。因此可以对 B+ 树进行两种查找运算:一种是从最小关键字起顺序查找,另一种是从根节点开始,进行随机查找。 在 B+ 树上进行随机查找、插入和删除的过程基本上与 B 树类似。只是在查找时,若非终端结点上的关键码等于给定值,并不终止,而是继续向下直到叶子结点。因此,对于 B+ 树,不管查找成功与否,每次查找都是走了一条从根到叶子结点的路径。

B/B+ 树通过对每个节点存储个数的扩展,使得对连续的数据能够进行较快的定位和访问,能够有效减少查找时间,提高存储的空间局部性从而减少 IO 操作,常用于文件系统和数据库系统。

6 散列表

散列表又称哈希表,是一个根据关键码值(key-value)而直接进行访问的数据结构,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

我们之前介绍过,数组寻址容易,插入和删除困难;链表寻址困难,插入和删除容易。哈希表使用了数组与链表两种数据结构,同时也综合了数组和链表两者的优点,寻址容易,插入删除也容易。

哈希表将 key 通过哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将 value 存储在以该数字为下标的数组空间里。当使用哈希表进行查询的时候,再次使用哈希函数将 key 转换为对应的数组下标,并定位到该空间获取 value。

7 堆

堆分为最大堆和最小堆两种。堆的性质如下:

  1. 堆树是一颗完全二叉树
  2. 堆树中某个节点的值总是不大于或不小于其孩子节点的值
  3. 堆树中每个节点的子树都是堆树

当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆,当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆。

下图为最大堆:

下图为最小堆:

8 图

一个图就是一些顶点的集合,这些顶点通过一系列边连接。图有各种形状和大小,边可以有权重,也可以有方向。

图算法一般有深度优先搜索和广度优先搜索,如果一个问题可以通过顶点和边表示,那么可以运用相应的算法解决问题。

至于如何描述一个图,有两种主要的方法:

  1. 邻接列表:每一个顶点会存储一个从它这里开始的边的列表

  1. 邻接矩阵:行和列都表示顶点,由两个顶点所决定的矩阵对应元素表示这里两个顶点是否相连,如果相连的话,这个值表示的是相连边的权重

参考:数据结构:链表(linked-list)
常用数据结构——树
哈希表(散列表)原理详解
数据结构:图(Graph)
数据结构:八大数据结构分类

入门数据结构,看这一篇就够了!相关推荐

  1. 关于做Kaggle比赛入门,看完这篇就够了

    PART 0 : Kaggle 介绍 Kaggle的数据挖掘比赛近年来很火,以至于中国兴起了很多很多类似的比赛 Kaggle 是一个数据科学竞赛的平台,很多公司会发布一些接近真实业务的问题,吸引爱好数 ...

  2. Kaggle入门,看这一篇就够了

    转载地址:https://zhuanlan.zhihu.com/p/25686876 之前发表了这篇关于 Kaggle 的专栏,旨在帮助对数据科学( Data Science )有兴趣的同学们更好的了 ...

  3. 关于Kaggle入门,看这一篇就够了

    这次酝酿了很久想给大家讲一些关于Kaggle那点儿事,帮助对数据科学(Data Science)有兴趣的同学们更好的了解这个项目,最好能亲身参与进来,体会一下学校所学的东西和想要解决一个实际的问题所需 ...

  4. Apache Spark处理大数据入门,看这一篇就够了

    作者 Srini Penchikala ,译者 丛一 什么是Spark Apache Spark是一个围绕速度.易用性和复杂分析构建的大数据处理框架.最初在2009年由加州大学伯克利分校的AMPLab ...

  5. python画图网格线设置_Matplotlib可视化入门,看这一篇就够了

    Matplotlib是 Python 最著名的2D绘图库,提供了丰富的数据绘图工具,主要用于绘制一些统计图形.Matplotlib可用于Python脚本,Python和IPython shell,Ju ...

  6. 小程序 getphonenumber_小程序入门,看这一篇就够了!

    文章为实战中踩坑经历,以及解决方案.同时是自己的一个项目回顾,在这里分享给大家,希望能帮助到大家.文章内代码需要左右滑动噢~ 登录授权 授权(基本信息,手机号码 )必须使用小程序原生的的button组 ...

  7. @程序员,入门爬虫看这一篇就够了!

    最近,笔者在经常后台看到小伙伴留言在问,想学Python,但不知道如何入门? 其实对于这个问题,真是仁者见仁智者见智.有句老话说的好"一千个读者,就有一千个哈姆雷特"不过对于此疑惑 ...

  8. Flask入门,看这一篇就够了

    python笔记 Flask 路由配置篇 基本使用 综合案例--音乐网站 https://github.com/xishandong/Music_Web 在我们创建好的项目中,我们有一个基础的路由,如 ...

  9. GraphQL是什么,入门了解看这一篇就够了!

    文章目录 GraphQL产生背景 GraphQL组成结构 GraphQL执行原理 GraphQL-restAPI对比 部署架构 服务端-DataFetcher一种实现方式 graphql与Spring ...

  10. docker入门,看这一篇就够啦

    简介 Docker是一个开源的应用容器引擎,通过容器可以隔离应用程序的运行时环境(程序运行时依赖的各种库和配置),比虚拟机更轻量(虚拟机在操作系统层面进行隔离).docker的另一个优点就是build ...

最新文章

  1. android hal 驱动,AndroidHAL-Teseo
  2. 百度资源管理平台 站长工具 批量添加主站域名 子站域名 域名主动推送
  3. redhat中linux的ip配置文件,RedhatLinux配置大量ip地址的方法
  4. python中csv模块读写文件
  5. 处理大并发之二 对epoll的理解,epoll客户端服务端代码
  6. 不是所有问题都适合用神经网络去搞!
  7. 【2017年第4期】流式大数据实时处理技术、平台及应用
  8. WinRAR压缩加密的做法
  9. drf之day09:内置的认证类,权限类,频率类,django配置文件解析,过滤类的其他作用,全局异常处理,接口文档
  10. 六一小学生计算机创新活动总结,2020小学生六一儿童节活动总结
  11. 我与龙芯电脑的第一次亲密接触
  12. 新浪邮箱界面登录按钮效果制作
  13. Python数据分析 | (31) 透视表和交叉表
  14. 线性回归模型 —— 普通最小二乘法(OLS)推导与python实现
  15. Linux命令-PV
  16. matplotlib+basemap画出标记地图
  17. 浙江工商大学计算机考试科目,浙江工商大学(专业学位)计算机技术研究生考试科目和考研参考书目...
  18. 语音唤醒 mycroft-precise使用记录
  19. windows php java_Windows下配置 php-java-bridge
  20. 电竞游戏而生,这款高清显示器要逆天了~

热门文章

  1. 在Odunpazari现代博物馆,棉花糖激光盛宴以不同寻常的方式将自然带入生活
  2. 搭建开发平台—WTK
  3. 什么是划分子网?网络工程师划分子网有啥技巧?
  4. 唱好铁血丹心谐音正规_铁血丹心 谐音
  5. Java面试汇总四 当下主流MQ消息队列的优缺点
  6. MATLAB 2017a \b、2016a\b等高版本,打开函数帮助文档需要登录MATHworks账户且需要绑定产品
  7. Base128编码规范
  8. 《养个女儿做老婆》读后感
  9. 云台控制协议VISCA、PELCO-D、PELCO-P
  10. 操作系统原理,进程的基本状态,运行态,就绪态,等待态与转换模型,进程的其他状态,创建,终止,挂起与转换模型,Linux进程状态模型示例