mysql---金丹篇(一)---数据结构之二叉树

 1、问答

1、红黑树了解么,时间复杂度?

 

2、什么是B+树素引?为什么使用B+树?BTree机制说一下?B+tree 如何进行优化?二叉树的转置是什么?

MySQL索引类型有?如何管理 MySQL索引?什么是索引?什么是索引覆盖?什么是聚簇索引?什么是非聚簇索引?对比一下B+树索引和 Hash索引?什么是联合索引?

索引利弊是什么及索引分类?各自索引有哪些优缺点?浅谈索引优化?

聚簇索引和非聚簇索引的区别?

索引遵循哪些原则?存储引擎会进行哪些自动优化?到底何时索引会失效?

索引与锁有什么关系?

 

 

讲讲Innodb行锁?
死锁及监控是什么?
自增长与锁 ,锁的算法,锁问题,锁升级是什么?
谈谈MySQL的锁并发?

乐观锁是怎样的?
乐观锁悲观锁区别是什么?
数据库如何实现悲观锁和乐观锁?
数据库锁和隔高级别有什么关系?
数据库锁和索引有什么关系?

索引最左前缀是什么?
MySQL表设计及规范?
什么是回表?

讲讲表与表之间的关系?分库分表,设计可动态打容缩的分库分表,分库分表之后全局id的生成


MySQL读写分离及主从同步延时解决方案,MySQL主从复制怎么实现的?具体原理是什么?有什么优缺点?

InnoDB支持的四种事务隔离级别名称是什么?有什么却别?说说MySQL隔离级别?
事务的特性及慢查询?

说说MySQL常用的优化方法?对Explain参数及重要参数的理解?

说说MySQL几种存储引擎应用场景?都有什么区别?






谈谈对Innodb事务的理解?
说说数据库事务特点及潜在问题?
什么是MySQL隔离级别?
有多少种事务失效的场景,如何解决?
Innodb如何解决幻读?


了解查询优化器模块;
查询优化的基本思路是什么?
说说MySQL读写分离、分库分表?


JOIN的原理是什么?

Query语句对数据库性能有什么影响?
表结构对性能有什么影响?
MySQL瓶颈分析?说说Sql优化的几点原则?MySQL常用优化方式有哪些?



MySQL常用监控?

 

2、树的演进过程

基本概念

双亲—— 孩子结点的上层结点叫该结点的双亲
兄弟—— 同一双亲的孩子之间互成为兄弟
祖先—— 结点的祖先是从根到该结点所经分支上的所有结点
子孙—— 以某结点为根的子树中的任一结点都成为该结点的子孙
结点的层次—— 从根结点算起,根为第一层,它的孩子为第二层……
堂兄弟—— 其双亲在同一层的结点互称为堂兄弟。
有序树—— 如果将树中结点的各子树看成从左至右是有次序的(即不能互换),则称该树为有序树,否则称为无序树。在有序树中最左边的子树的根称为第一个孩子,最右边的称为最后一个孩子。
森林—— m(m>0)棵互不相交的树的集合

2.1 树

树是互不相交的n个节点(n>=0)有限集.

n=0时称为空树.

n=1时仅有一个根节点。

当n>1时,其余结点可分为个互不相交的有限集(T1、T2、......、Tn),其中每一个集合又是一棵树,并且称为根的子树。子树的个数没有限制,但它们一定是互不相交的

树的度:结点拥有的子树数目或最大分支数称为结点的度。如图A节点有b、c2个子树,她的度为2,J节点没有子树,它的度为0。

数的层次:从根开始定义起,根为第一层,根的孩子为第二层,以此类推,如图。

树的深度:树中结点的最大层次数称为树的深度高度。如图所示树的深度为4。

叶子结点:度为0的结点,即没有子节点。如GHIJ都是叶子节点。

内部结点:也叫中间节点,除去根节点和叶子节点的其它节点。

2.2 二叉树

二叉树即每个结点都最多只有两个子结点的树。

二叉树有以下特点:

1)每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。
2)左子树和右子树是有顺序的,次序不能任意颠倒。
3)即使树中某结点只有一棵子树,也要区分它是左子树还是右子树

二叉树性质

1)在二叉树的第i层上最多有2i-1 个节点 。(i>=1)
2)二叉树中如果深度为k,那么最多有2k-1个节点。(k>=1)
3)n0=n2+1, n0表示度数为0的节点数,n2表示度数为2的节点数。
4)在完全二叉树中,具有n个节点的完全二叉树的深度为[log2n]+1,其中[log2n]是向下取整。
5)若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中

2.2.1 普通二叉树

2.2.2  斜树

所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。这两者统称为斜树

                                                    

2.2.3 完全二叉树

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1层) 的结点数都达到最大个数第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

   

 如图,第一幅图,1~2层每层都达到了最大节点数。第二幅图,第一层有1个节点,第二层有2个节点,第三层有4个节点,都达到了最大节点数。

2.2.3 满二叉树

美国以及国际上所定义的满二叉树,即full binary tree,和国内的定义不同

国际定义的满二叉树:除叶子节点外,每个结点都有左右子结点的二叉树。即树的结点要么是度为0的叶子结点,要么是度为2的结点,不存在度为1的结点。

国内定义的满二叉树:高度为h,由2^h-1个节点构成的二叉树称为满二叉树。即根节点左右子节点层级相同,除了最后一层外,其它各层节点度都为2.

   国际定义的满二叉树                                                    国内定义的满二叉树:

                       

2.2.4 二叉查找树

二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),也称为有序二叉查找树,它是一棵空树,或者是具有下列性质的二叉树

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

(4)没有键值相等的结点。

如果以6为根节点,依次插入6、3、7、8、2、5,它的机构如下

按照中序遍历的方式可以从小到大的顺序排序输出:2、3、5、6、7、8,下面演示使用2种查找方式查找数值为8的数

顺序查找:先找到2,不是8;再找到3,不是8;...直到按顺序找到8,共找了6次。所有数都按顺序查找的平均查找次数为(1+2+3+4+5+6)/ 6 = 3.3次。

二叉树进行查找:先找到根,其键值是6,6小于8,因此查找6的右子树;找到7;而7小于8;再找其右子树,直到找到8;一共找了3次。二叉查找树的平均查找次数为(3+3+3+2+2+1)/6=2.3次。

由此可见:二叉查找树的平均查找速度比顺序查找来得更快。

但是随着节点的添加和删除,二叉查找树会退化为线性树。

例如:如果根节点选择是最小或者最大的数,如根节点是2,数字以2、3、5、6、7、8顺序插入,按二叉查找树排序,就完全退化成了线性结构

平均查找次数为(1+2+3+4+5+6)/6=3.3次,和顺序查找差不多,一颗二叉查找树的优势完全丧失了.

若想最大性能的构造一个二叉查找树,需要这个二叉树是平衡的,从而引出了一个新的定义-平衡二叉树AVL

二叉树的应用场景:
普通的二叉树,很难构成现实的应用场景,但因其简单,常用于学习研究,平衡二叉树则是实际应用比较多的。常见于快速匹配、搜索等方面。
常用的树有:AVL树、红黑树、B+树、Trie(字典)树
1、AVL树: 最早的平衡二叉树之一。应用相对其他数据结构比较少。windows对进程地址空间的管理用到了AVL树。
2、红黑树: 平衡二叉树,广泛用在C++的STL中。如map和set都是用红黑树实现的。还有Linux文件管理。
3、B/B+树: 用在磁盘文件组织 数据索引和数据库索引。
4、Trie树(字典树): 用在统计和排序大量字符串,如自动机、M数据库索引

2.2.5 平衡二叉树

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),是一种高度平衡二叉树

具有以下性质:

它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

它是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1),不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入删除次数比较少,但查找多的情况。 

注意:在大量查找的情况下,平衡二叉树的效率更高,也是首要选择。在大量增删的情况下,红黑树是首选。

在插入的情况下平衡二叉树需要维持高度平衡,这也就意味着在大量插入和删除节点的场景下,需要调整的频率会更高

删除时,对于平衡二叉树来说,最坏情况下,需要维护从被删节点到根节点这条路径上所有节点的平衡性,旋转的量级是O(logN)。但是红黑树就不一样了,最多只需3次旋转就会重新平衡,旋转的量级是O(1)。

应用

Windows NT内核中广泛存在

2.2.6 红黑树

它是一种自平衡二叉查找树,也叫弱平衡二叉树,相对于要求严格的AVL树来说,它的旋转次数变少,所以对于搜索、插入、删除操作多的情况下,我们就用红黑树。

在二叉查找树基础上,添加以下性质

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

正式因为有了这些规则限制,才保证了红黑树的自平衡

时间复杂度为O(lgn),如图

当插入或删除的时候,红黑树规则可能被打破。什么情况下会破坏红黑树的规则,什么情况下不会破坏规则呢?

     向原红黑树插入值为14的新节点,没破坏规则:                    向原红黑树插入值为21的新节点,破坏了规则4(红色节点的子节点都是黑色)

   

必须进行调整,使之重新符合红黑树的规则,调整有2种方法

  • 变色
  • 旋转:左旋转和右旋转

变色:使用变色方法进行调整流程,如图

 step1:把22变为黑色,凭空多出的黑色节点打破了规则5        step2:继续把节点25从黑色变成红色,发生连锁反应           step3:继续把红色节点27变为黑色

                      

左旋转:逆时针旋转红黑树的两个节点,使得父节点被自己的右孩子取代,而自己成为自己的左孩子。

如图:身为右孩子的Y取代了X的位置,而X变成了自己的左孩子。此为左旋转

右旋转:顺时针旋转红黑树的两个节点,使得父节点被自己的左孩子取代,而自己成为自己的右孩子。

如图:身为左孩子的Y取代了X的位置,而X变成了自己的右孩子。此为右旋转

下面我们以刚才插入节点21的情况为例,演示是使用变色还是旋转。

先使用变色,把节点25及其下方的节点变色,

此时节点17和节点25是连续的两个红色节点,那么把节点17变成黑色节点?这样一来不但打破了规则4,而且根据规则2(根节点是黑色),也不可能把节点13变成红色节点。

变色已无法解决问题,我们把节点13看做X,把节点17看做Y,像刚才的示意图那样进行左旋转:

     

由于根节点必须是黑色节点,所以需要变色,变色结果如下:

 

此时路径(17 -> 8 -> 6 -> NIL)的黑色节点个数是4,其他路径的黑色节点个数是3,不符合规则5。这时候我们需要把节点13看做X,节点8看做Y,像刚才的示意图那样进行右旋转

                    

 最后根据规则来进行变色:

 

如此一来,我们的红黑树变得重新符合规则。这一个例子的调整过程比较复杂,经历了如下步骤:变色 -> 左旋转 -> 变色 -> 右旋转 -> 变色

应用

1、广泛用于C++的STL中,Map和Set都是用红黑树实现的; 
2、著名的Linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块,进程的虚拟内存区域都存储在一颗红黑树上,每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址虚拟存储区域,右指针指向相邻的高地址虚拟地址空间; 
3、IO多路复用epoll的实现采用红黑树组织管理sockfd,以支持快速的增删改查; 
4、Nginx中用红黑树管理timer,因为红黑树是有序的,可以很快的得到距离当前最小的定时器; 
5、Java中TreeMap的实现;

2.2 二叉树遍历

前序遍历(前根遍历):根——>左——>右

中序遍历(中根遍历):左——>根——>右

后序遍历(后根遍历):左——>右——>根

层次遍历:层次从上到下,每层从左到右

前序遍历

先序遍历:(1)访问根节点;(2)先序递归遍历左子树;(3)先序递归遍历右子树;

先序遍历结果:A BDFE CGHI

中序遍历

中序遍历:(1)中序遍历左子树;(2)访问根节点;(3)中序遍历右子树

中序遍历结果:DBEF    A    GHCI

后序遍历

后序遍历:(1)后序递归遍历左子树;(2)后序递归遍历右子树;(3)访问根节点;

后序遍历的结果:DEFB  HGIC   A

层序遍历

从树的第一层,也就是根节点开始访问,从上到下逐层遍历,在同一层中,按从左到右的顺序结点逐个访问。

 

2.3 二叉树村存储结构

2.3.1 顺序存储

二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结点。因此,必须把二叉树的所有结点安排成为一个恰当的序列,用编号的方法从树根起,自上层至下层,每层自左至右地给所有结点编号,缺点是有可能对存储空间造成极大的浪费,在最坏的情况下,一个深度为k且只有k个结点的右单支树需要2k-1个结点存储空间。

依据二叉树的性质,完全二叉树和满二叉树采用顺序存储比较合适,树中结点的序号可以唯一地反映出结点之间的逻辑关系,这样既能够最大可能地节省存储空间,又可以利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系。

存储在数组中

 最差的情况如下,线性结构的二叉树,对存储空间造成了极大的浪费

 其中,∧表示数组中此位置没有存储结点

2.3.2 链式存储结构

由二叉树定义可知,二叉树的每个结点最多有两个孩子。因此,可以将结点数据结构定义为一个数据和两个指针域,这种链表叫做二叉链表,如图

节点代码

typedef struct BiTNode{
    TElemType data;//数据
    struct BiTNode *lchild, *rchild;//左右孩子指针
} BiTNode, *BiTree;

为了方便访问某结点的双亲,还可以给链表结点增加一个双亲字段parent,用来指向其双亲结点。每个结点由四个域组成,其结点结构为:

这种存储结构既便于查找孩子结点,又便于查找双亲结点;但是,相对于二叉链表存储结构而言,它增加了空间开销。利用这样的结点结构表示的二叉树的链式存储结构被称为三叉链表

 

节点代码

#define datatype char  //定义二叉树元素的数据类型为字符
typedef struct  node {  //定义结点由数据域,左右指针组成
     Datatype data;
     struct node *lchild,*rchild,*parent;
 }Bitree;

3、时间复杂度的规则与计算 

最优时间复杂度:算法完成工作最少需要多少基本操作.其反映的只是最乐观最理想的情况,没有参考价值.

最坏时间复杂度:算法完成工作最多需要多少基本操作.提供了一种保证,表明算法在此种程度的基本操作中一定能完成工作

平均时间复杂度 :算法完成工作平均需要多少基本操作.是对算法的一个全面评价,因此它完整全面的反映了这个算法的性质

时间复杂度的几条基本计算规则
基本操作,即只有常数项,认为其时间复杂度为O(1)
顺序结构,时间复杂度按加法进行计算
循环结构,时间复杂度按乘法进行计算
分支结构,时间复杂度取最大值
判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度

常见时间复杂度

执行次数函数举例非正式术语
12 O(1) 常数阶
2n+3 O(n) 线性阶
3n2+2n+1 O(n2) 平方阶
5log2n+20 O(logn) 对数阶
2n+3nlog2n+19 O(nlogn) nlogn阶
6n3+2n2+3n+4 O(n3) 立方阶
2n O(2n) 指数阶

 

 

 

注意,经常将log2n(以2为底的对数)简写成logn。lne2(以e为底的对数)写成ln2

所消耗的时间从小到大

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn

 

 

参考文档:

B-Tree,B+Tree以及mysql索引的实现

https://blog.csdn.net/sinat_36722750/article/details/82946311

MySQL系列-B+Tree索引详解

https://blog.csdn.net/UFO___/article/details/80522453

MySQL系列-系统架构及存储引擎介绍

https://blog.csdn.net/UFO___/article/details/80519309

B树和B+树数据结构及使用场景

https://blog.csdn.net/qq_38238296/article/details/88362635

B+Tree原理及mysql的索引分析

https://www.cnblogs.com/xiaoxi/p/6894610.html

B树B-树和B+树的总结

https://open.toutiao.com/a6769472742832996877/?utm_medium=webview&vivo_news_comment_data=%7B%7D&vivo_news_source=1&vivo_news_comment_data_checksum=99914b932bd37a50b983c5e7c90ae93b&isNews=1&showOriginalComments=true&req_id=2019121407544801001401904422B9180D&crypt=5587&item_id=6769472742832996877&showComments=0&gy=2a8d3612778e2cf097372a2c3a21dbad1b3466d040348083237cf2e45b94fdae358665bc74c6eb1485e5ed19d06eb230ef07bc4c534673942907ea174cb240234e97a27571915331963ea79749950d97008d4d721550dcf23dd5b9d8078da4e95ac249bc39c77ad5b9ec78d61e6be56d4c671cd609e027502ed387b925fb8e55280e2d9ecd4449ba09ed1e322d0431d6&a_t=31158380437568786751332dce1&label=vivo_llq_channel&utm_source=vivoliulanqi&utm_campaign=open&dt=vivo%20X9

看了这么多篇红黑树文章,你都理解了嘛?

https://open.toutiao.com/a6739678098108711432/?utm_medium=webview&vivo_news_comment_data=%7B%7D&vivo_news_source=1&vivo_news_comment_data_checksum=99914b932bd37a50b983c5e7c90ae93b&isNews=1&showOriginalComments=true&req_id=2019121408465801001206109423C40CD0&crypt=5268&item_id=6739678098108711432&showComments=0&gy=3006ce77496da435474b365b461bf44c6208c62d614f95dfaef6027f46771e10eba35c9791f6b165a2dc39bfd342c647436bc06dd9513d69ece08f40c907ce161262e9bafa1d98434c5aa5fb5799521e201f63d8000ed340474acf3a8bed77b9c85df43c567c0bf5f6a9efd562042978098f5354fb346ccaecd4e890624fa4580b151f42488829a33af707fadfdbd5fe&a_t=31158380437568786751332dce1&label=vivo_llq_channel&utm_source=vivoliulanqi&utm_campaign=open&dt=vivo%20X9

什么是红黑树?(画图讲解,比较容易理解)

https://blog.csdn.net/qq_36610462/article/details/83277524

复杂度分析(大O表示法)

https://blog.csdn.net/weixin_42313246/article/details/108315179

 

posted @   六只小猫  阅读(429)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示