上篇文章咱们主要介绍了线性数据结构,本篇233酱带你们康康 无所不在的非线性数据结构之一:树形结构的特色和应用。面试
树形结构,是指:数据元素之间的关系像一颗树的数据结构。咱们看图说话:
它具备如下特色:sql
维基百科中列举了计算机科学中树形结构的种类
233酱固然不会一个个讲,咱们只挑一些熟悉的面孔:多叉树,二叉树,二叉查找树,红黑树,堆,Trie树,B树,B+树,LSM Tree,了解他们在对不一样规模的数据 增,删,改,查 时所起到的做用就够了。mongodb
限于篇幅,本文主要介绍非LSM Tree的内容。数据库
树体现了一种 继承 的关系,节点之间为父子关系。多叉树 是指一个父节点能够有多个子节点。也就是:爸爸能够有多个儿子,儿子只能有一个爸爸。
当须要这种分层,继承的场景下都可以考虑用树结构来实现,能够简化咱们对数据关系的描述。数组
此外,节点的每一个分支也表明着一种选择,能够用来作决策。缓存
应用场景:
1.Linux文件系统
2.组织关系表示,如公司的组织架构,角色权限系统等。
3.XML/HTML数据。
4.类的继承关系
5.决策,如游戏中怪物使用的技能选择,机器学习...
二叉树(Binary tree)是每一个节点最多只有两个分支(即不存在分支度大于2的节点)的树结构,也就是说 爸爸 最多只能有 两个儿子。
由于计算机应用中存在不少“非黑即白”的场景,一样咱们能够利用 不是走左分支,就是走右分支 这种结构选择来作一些决策。
另外,利用每一个节点下参与方最多为两个,也能够作一些事情。数据结构
应用场景:
1.编译器的语法树构造。
2.表达式求值和判断:非叶子节点为操做符,叶子节点为数值。
3.Boolean求值,如(a and b)or (c or d)
。
4.霍夫曼编码
5.IPv4路由表的存储...
在咱们的平常开发中,常常须要对数据进行增删改查,每个步骤的时间空间效率决定了应用最终的性能。架构
时间复杂度 体如今 可否快速定位到要操做的数据元素,核心在于 索引的好坏;机器学习
空间复杂度 体如今 可否占用 更小的内存空间,可否利用计算机各层介质的缓存性能提升访问速度(访问速度:CPU>> 内存>>磁盘)。性能
在如下树形结构的讨论中,但愿小伙伴能多从 索引,所占用内存空间,操做的介质 这些方面考虑数据的增删改查性能。
二叉查找树(Binary Search Tree)首先是二叉树,同时知足必定的有序性:节点的左子节点比本身小,节点的右子节点比本身大。
这样当咱们定位一个元素的位置时,从根节点开始查找,小于节点左拐,大于节点右拐。等于节点排序值就恰好找到。二分的索引思想就体如今其中。
应用场景:
二叉查找树的有序性是它可以普遍应用的缘由。可是可否高效二分体如今树的高度合理性上。下面要讲的 红黑树/堆结构才是其普遍应用。
二叉查找树的缺点在于:只限制了节点的有序性,但有序树的构造有好坏。一颗“坏”的有序树直接会被拉成 “有序链表”。因此须要经过必定的条件保证树的平衡性。
树的平衡性是指整棵树的最高子树和最矮子树相差不大,这样整棵树的高度相对来讲低一些,相应的增,删,改,查操做的效率较高较稳定(与树高有关)。
红黑树(Red–black tree)是应用很普遍的一种平衡树,是面试官的装X利器。咱们来看一下它保证平衡性的一些特性:
这些约束确保了红黑树的关键特性:从根到叶子的最长路径很少于最短路径的两倍长(根据性质4和性质5)。从而整棵树的高度比较稳定,相应的增、删、改、查操做的效率较高较稳定,而不一样于普通的二叉查找树。
此外相比其余的平衡树:如高度平衡树AVL树,红黑树的增删改效率较高,同时查找性能没有降低不少也比较稳定。因此工业级应用更为普遍。
应用场景:适合排序,查找的场景。
1.容器的基本组成,如Java中的HashMap/TreeMap.
2.Linux内核的彻底公平调度器
3.Linux中epoll机制的实现...
堆是一种特殊的数据结构,它知足两个特性:
这里解释如下彻底二叉树。它是指:除了最后一层,其余层的节点个数都是满的,最后一层的节点都靠左排列。
这样咱们就能够用数组来存储。
假设根节点在i=0的位置:若是父节点的数组下标为i
,则左子节点的数组下标为2 * i+1
,右子节点的数组下标为 2 * i + 2
。数组比链表的存储好处上篇文章233酱提过了,这里就不赘述了。
针对第2点,若是每一个节点的值都大于等于子树中每一个节点值的堆,叫作“大顶堆”。反之叫作“小顶堆”。
堆这种结构相对有序,且堆顶元素要么最小,要么最大。且利用了 数组和自身特性 增删改查的时间复杂度较低。
应用场景:
1.堆排序
2.TopK,求中位数,求
3.合并多个有序小文件或集合
4.优先队列,如定时任务的存储等...
Trie树 又称前缀树或字典树,它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。
它的特性为:
若是咱们有and,as,at,cn,com这些关键词,那么构建的trie树以下:
Trie 树的本质,就是利用字符串之间的公共前缀,将重复的前缀合并在一块儿。这样当咱们查找某个字符串时,只须要在Trie树上匹配字符串的每一个字符,比较次数仅和 字符串的长度 有关。
可是Trie 树的缺点就是构造Trie树须要很大的内存空间。由于父子字符节点之间用 指针关联。若是用数组保存这些指针,这意味着子节点的数组须要穷举出每一种可能。如子节点字符为a-z,就须要分配长度为26的数组来存储这些可能的子节点。
改进内存分配的措施有:
1.子节点指针改成用:有序数组、跳表、散列表、红黑树来存储。
2.子节点合并,如原来 hello存储为:h->e->l->l->o ,如今可存储为:h->e->llo
Trie 树毕竟比较浪费空间,因此它在字符串的查找中,适合用于:1.字符集不能太大 2.字符串的公共前缀较多 的场景。
应用场景:
1.关键词匹配,提示,纠错。
2.最长公共前缀匹配。
3.命令自动补全,如zsh.
4.网址浏览历史记录。
5.手机号码簿查询...
B树、B+树、LSM Tree是数据库中常常出现的数据结构。对于数据库的增删改查效率,须要考虑的首要因素是:磁盘的IO访问次数。
如何减小IO访问次数?
前文咱们已经提到了索引,可是IO一次不容易,从磁盘中获取数据一般是以块为单位的。若是对于上千万条数据,咱们只创建一层索引结构的话,那索引的数据量也是巨大的。
如何下降索引量?
假设咱们到全世界找一我的,咱们是按照 国家/省/市/区/街道/小区的顺序来定位。同理,随着数据量的增大,咱们须要一层层的创建 多级索引 。越上层的索引每一个块中表示的数据范围越大。
如何保证咱们创建的多级索引 是“合适”的?
这个合适主要指:存储的数据量大而且树高小。同红黑树同样,咱们须要一些 限制条件 来保证树高。这也就是如下数据结构的限制条件缘由了。
一个m阶(该树每一个节点最多有 M 个子节点)的B树具备如下特征:
1.根节点至少有两个子女。
2.每一个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m
3.每个叶子节点都包含k-1个元素,其中 m/2 <= k <= m
4.全部的叶子节点都位于同一层。
5.每一个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。
一个3阶的B树插入示意图以下:
应用场景:MongoDB
一个m阶的B+树具备如下特征:
1.有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每一个元素不保存数据,只用来索引,全部数据都保存在叶子节点。
2.全部的叶子节点中包含了所有元素的信息,及指向含这些元素记录的指针,且叶子节点自己依关键字的大小自小而大顺序连接。
3.全部的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。
看不懂不要紧,咱们只须要知道这些限制条件是为了让B+树数据“矮而胖”就好。
这里我直接放张掘金小册《从根儿上理解MYSQL》B+树主键索引的示意图:
应用场景
1.Mysql InnoDB存储引擎。
看到这里常考面试题来了:B树和B+树有什么区别?为何Mongo用B树?为何Mysql用B+树?
看图说话,B树 和 B+树显著不一样的地方是:
1.B树非叶子节点便是索引,也是数据;B+树非叶子节点仅是索引,数据所有存储在叶子节点。
2.B+树叶子节点的数据之间是用链表连接的。
这会致使:
B+树相比B树:
1.数据的连续性:
2.叶子结点之间的链接性:
B树相比B+树:
看成单一数据查询时,B树的结点平均离根结点更近,平均查询效率比B+树快。
总结一下:B+树相比B树,前者更适合范围查询,后者更适合单一数据查询。
Mongo是非关系型数据库,数据之间的关系用嵌套解决。它的主要使用场景是: 追求 单个读写记录的性能。
Mysql是关系型数据库,数据之间的关系用共同的索引键,Join解决。它的使用场景:不只存在大量的单一数据查询,也存在大量的范围查询。
因此上面的问题能够简单扯一扯了吧。
下篇文章233酱准备介绍近几年数据库中常常出现的角色:LSM Tree。以为本文有收获 or 期待下篇 请四连【关注,点赞,在看,转发】支持下233吧~
参考资料:
[1].维基百科
[2].https://www.youtube.com/watch?v=OJ5NYq1Eii8
[3].https://time.geekbang.org/column/article/72414
[4].https://towardsdatascience.com/8-useful-tree-data-structures-worth-knowing-8532c7231e8c
[5].https://draveness.me/whys-the-design-mongodb-b-tree/