从MySQL开始聊聊“树”结构 (上)

image.png

前言

嗨喽,你们好,我是CrazyCodes, 近一年写的文章,都是一些广度方面的思考,新的一年,在技术深度上也须要有更多的探索,感谢各位的持续支持!算法

MySQL

image.png

先聊聊你们熟知的MySQL,咱们使用MySQL确定是有数据存储的需求。数据库

咱们从基础开始看,首先咱们建立一张用户表数组

CREATE TABLE `user` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

这是一张简单的用户表,包含id和name两个字段,id为主键自增,name上没有索引。想必你们对索引都有必定的认识,索引是一种数据结构,即本篇的核心议题“树”结构,索引能够达到快速命中某条记录,“快速”一词表明着在时间和空间相结合的最优解,固然也并不表明索引越多,数据表设计越合理,要根据实际业务去选择。数据结构

咱们随机向表中插入几条记录学习

INSERT INTO `user` VALUES(1,"Join");
INSERT INTO `user` VALUES(2,"Tom");
INSERT INTO `user` VALUES(3,"Jeein");

按照预期,数据库内出现三条对应的记录,这里我使用语句spa

SELECT * FROM `user`;

对数据进行查询
image.png
看到这里,你可能说了,这是在讲什么,增删改查都是常识,有什么好讲的,那咱们如今就正式进入正题,首先从插入记录开始提及,MySQL会使用B+树来存储数据记录,B+树是B树的延伸,而B树又是平衡二叉树的延伸,除了平衡二叉树还有二叉查找树,依次基于其概念延伸的排序,大概是以下这样设计

B+树 -> B树 -> 平衡二叉树 -> 二叉查找树 -> 二叉树 -> 树

固然也不只仅是全部跟树有关的数据结构,这里为了提升学习树这种数据结构的兴趣,因此以MySQL讲起,纠其根源,再结合MySQL的数据记录将这一串知识连接起来,那咱们把这个顺序倒过来依次讲起3d

树 -> 二叉树 -> 二叉查找树 -> 平衡二叉树 -> B树 -> B+树

我尽可能不把这些数据结构讲成教科书的样子。code

树🌲

image.png
你要不知道树是什么玩意,就别继续看下去了😂,就是大街上咱们看到的树,大街的树也就是咱们常识认知的树,是经过“树根”、“树枝”和“树叶”组成,缺同样,这树也不是一颗完整的树。blog

那么数据结构中的树指的什么,你能够把手机或者电脑倒过来看上图,数据结构中的树,就是一个倒过来的树,并非他非要倒过来才能说,而是根据人类正常的视觉与思惟,就例如你看书总不能从最后一页的最后一个字开始从后往前读把,倒过来只是便于理解和阅读它罢了。

在数据结构中倒过来的树大概是张下面这个样子

倒树
image.png

正树
image.png

正树、倒树,都贴出来了,你能够尝试对比这两张图,看看那张图更容易理解,接下来的案例只会以倒树展现。

树是其余树型数据结构的基础,这里你必需要熟记一些基本概念

  • 树根,树的根节点
  • 子节点,树枝1、2、三是树根的子节点
  • 兄弟节点,树枝1、2、三互为兄弟节点
  • 父节点,树根是树枝一的父节点,树枝一是树枝1-1的父节点

相信根据上图多看几遍,这很容易理解

那咱们生搬硬套,把MySQL的数据放到这个最简单的树中
image.png
这是我随意摆放的,固然你想怎么摆就怎么摆,例如
image.png
这看起来像跟棍,或者
image.png
不管怎样,咱们建立了一个树,那根据SQL语句

SELECT * FROM `user`;

咱们须要查到根节点,这很简单,而后去判断根节点的左子节点是否有值,有的话取出来,右子节点也是同样的道理,这就是所谓的树的遍历。那么咱们如今在SQL上加些条件

SELECT * FROM `user` WHERE `id` = 1;

image.png

那这个条件,在树结构中如何查呢,到这里,你会发现一个问题

不管条件是什么,咱们都须要遍历整棵树,遍历树的深度,彻底取决于要查询的数据所在的位置,位置靠前,就少遍历些,位置靠后就多遍历下。

这里讲一个更基础的知识,时间复杂度,时间复杂度用于表示某个算法所计算的时间长度,那咱们根据上面这个例子,能够分析出其平均时间复杂度为 O(n) , 固然最好的状况是 O(1) , 这种状况就是根节点就是咱们要找的数据。

数据的不断增长,才使得咱们没法继续使用最原始的数据结构,哎,都是数据逼得呀。

假设咱们不只仅有3条记录,而是在3000万条查找Join,恰巧仍是第3000万条,那么若是使用最基本的树结构去查询的话,那么咱们将要进行3000万去查询才能够得到最终结果。是否是感受不切实际了?

其实这样的话,是否是树结构都不重要了,他能够是一个数组、链表或者队列等等,能够用任意数据结构去存储,固然每种数据结构的出现都有其存在的缘由。那么咱们使用原始树的结构感受不靠谱,那么跟随个人文字来到二叉树的世界!

二叉树

image.png

二叉树,顾名思义是只有两个叉的树,每一个节点只有两个叉,这是它的特性,这时候你就疑问了,为啥不能是三叉树,四叉树,N叉树呢?固然能够有,那么咱们举一个例子,咱们再往user表内插几行数据

INSERT INTO `user` VALUES(4,"Jorr");
INSERT INTO `user` VALUES(5,"Queie");
INSERT INTO `user` VALUES(6,"Kioa");

如今咱们库里有6条记录
image.png
咱们拿三叉树举例
image.png
我把每一个节点须要查询的次数列个表,这里我使用前序遍历树的方式,让你简单的清楚树有几叉意味着什么

tips :树有三种遍历方式,分别为 前序、中序、后序 ,根据具体需求使用不一样的遍历方式
节点 次数
1,join 1
3,jeein 2
5,queie 3
6,kioa 4
2,tom 5
4,jorr 6

若是是二叉树呢?
image.png

节点 次数
1,join 1
3,jeein 2
5,queie 3
6,kioa 4
2,tom 5
4,jorr 6

有没有很奇怪?不管几叉,查询4,jorr数据都须要6次,感受用哪一个都同样是不?并非这样,你能够这样考虑一个问题,在使用程序去遍历这两棵树时,二叉树须要判断左右子节点,而三叉树则须要判断左中右三个节点,他们所在的内存空间不一样,专业点说,他们的空间复杂度不一样。

解答了你的一点点小疑惑后,咱们回到正题,仍是聊聊二叉树的事。

二叉树分为彻底二叉树和不彻底二叉树

  • 彻底二叉树表明每一个节点都有2个树枝(就是不缺胳膊少腿)
  • 不彻底二叉树反之就是(缺胳膊少腿),某个树叉上可能只有左子树,没有右子树

上述展现了MySQL的数据生搬硬套放到二叉树中玩法,但你发现没?咱们依旧没法避免树被所有遍历的问题。

思考

我将在下一篇文章讲述剩余的“几颗树”,这里我给你留一道思考题。

问题一:树和二叉树(N叉树)都没法避免遍历整棵树,那下一篇要讲的平衡二叉树为何能够作到只须要遍历“半棵树”?

问题二:时间复杂度的表示方式 O(1) O(n) O(log2^n) 分别表明什么?

致谢

感谢你看到这里,2021 我会在思否发布本身电商设计的录播课,也是我首个录播课。

但愿本篇文章能够帮助到你,谢谢。

相关文章
相关标签/搜索