二叉搜索树,平衡二叉树,红黑树,B树,B+树

二叉树(BT)

树的一些基本概念:

  • 层数:从根结点开始,根结点的层次为1,根的直接后继层次为2,以此类推
  • 树的高度(深度):树中结点的最大层次

注:节点的深度&高度
二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)

两种特殊的二叉树:

1. 满二叉树

定义:只有度为0的结点和度为2的结点,并且度为0的结点在同一层上

如图:

2. 完全二叉树

定义:除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。

二叉搜索树(BST)

Binary Sort Tree,又称二叉查找树,二叉排序树,是一个有序树

满足以下条件:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

如图:

在这里插入图片描述

平衡二叉搜索树(AVL)

(注意,平衡二叉搜索树可简称为平衡二叉树,所以有的说法是平衡二叉树一定是二叉搜索树。但单独说平衡二叉树并没有要求是二叉搜索树。当然如果不是考试,死扣概念没有太大意义,所以平衡二叉树大多数情况都是二叉搜索树

1. 定义

【由一个姓 AV 的大佬(G. M. Adelson-Velsky) 和一个姓 L 的大佬( Evgenii Landis)提出。】

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

如图:

2. 如何保持平衡——旋转

当我们在一个平衡二叉树上插入一个结点时,有可能会导致失衡,这时就需要旋转来平衡,那怎么旋转呢?

基本步骤(以左旋为例):

第一步是确定支点:从添加的节点开始,不断的往父节点找不平衡的节点

第二步根据情况的不同

如果是下图情况:

  • 以不平衡的点作为支点
  • 把支点左旋降级,变成左子节点
  • 晋升原来的右子节点

如果是下图情况:

  • 以不平衡的点作为支点
  • 将根节点的右侧往左拉
  • 原先的右子节点变成新的父节点,并把多余的左子节点出让,给已经降级的根节点当右子节点

通常有四种情况

(1)LL:左左,当根节点的左子树的左子树有节点插入时—— 一次右旋

(2)LR:左右,当根节点的左子树的右子树有节点插入时—— 先局部左旋,再整体右旋

(3)RR:右右,当根节点的右子树的右子树有节点插入时—— 一次左旋

(4)RL:右左,当根节点的右子树的左子树有节点插入时—— 先局部右旋,再整体左旋

红黑树(RBTree)

1.定义

(1)一种自平衡的二叉搜索树
(2)不是高度平衡的
(3)特有的红黑规则(来维持平衡)

2.红黑规则

(1)每一个节点或是红色的,或者是黑色的

(2)根节点必须是黑色

(3)如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的(注意这里的叶节点是空节点

(4)如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况)

(5)对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点

如图:

在这里插入图片描述

每一个节点的示意图如下(比正常的二叉树节点多了一个颜色)

在这里插入图片描述

3.插入规则

首先明确一点,红黑树在插入一个节点时,效率最高的是插入红节点(如果插入的节点是黑色,那么这个节点所在路径比其他路径多出一个黑色节点,这个调整起来会比较麻烦,如果是红色,就不影响)

所以以下默认插入节点是红色,再根据情况来调整

在这里插入图片描述

B树

1.定义

首先可以把B树看作一个M树,并且允许一个结点中包含多个key,并且满足下列条件:
(1)树中每个结点最多有M-1个key(有M个孩子节点),并且以升序排列

(2)若根节点不是叶子结点,则根结点至少有两个孩子结点

(3)除根节点外,其他结点至少有m/2个孩子结点

(4)所有叶子结点都在同一层上,即B树是所有结点的平衡因子均等于0的多路查找树。

(5)每个节点的结构是:

在这里插入图片描述

其中n表示key的数量,Pi 是指向孩子的指针,ki 是其中一个key的值

B树示意图如下:

在这里插入图片描述

一般可以简画成:

在这里插入图片描述

2.在磁盘系统中的应用

在我们的程序中,不可避免的需要通过IO操作文件,而我们的文件是存储在磁盘上的。计算机操作磁盘上的文件是通过文件系统进行操作的,在文件系统中就使用到了B树这种数据结构。

其实讲到B树和B+树都离不开磁盘系统

在这里插入图片描述

查找文件或者数据都需要索引(更快的查询), 一般是通过 K:V(键值对)的形式,那么怎么设计一个文件系统的索引?(用什么样的数据结构)

如果设计的是线性形式,那查询效率肯定很低

如果设计成哈希表,如下图,会出现哈希冲突也会产生大量线性查询

在这里插入图片描述

又考虑到二叉树,上面介绍了很多种二叉树,都还不够吗?

  • 普通二叉树:数据无序,效率低
  • BST二叉搜索树是有序的,但如果原始数据是有序的,则会退化为线性查找
  • AVL平衡二叉树,当插入频率大于查找时,会消耗性能
  • 红黑树:其实已经解决了上面几种的缺点,但是当数据量很大,查询次数就会增多(数据量大,树的深度就会不断增加)

所以才考虑到B树——多路平衡查找树

由于存储介质的特性,磁盘本身存取就比主存慢很多,为提高效率,要尽量减少磁盘I/O。 所以磁盘往往不是严格按需读取,而是每次都会预读——局部性原理。由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此预读可以提高I/O效率

内存和磁盘发生数据交互时,一般情况下有一个最小逻辑单元,称为页,页一般由操作系统决定多大,一般是4k或者8k,预读的长度一般为页的整倍数

文件系统的设计者利用了磁盘预读原理,将一个结点的大小设为等于一个页(1024个字节或其整数倍),这样每个结点只需要一次I/O就可以完全载入。那么3层的B树可以容纳102410241024差不多10亿个数据(如果换成二叉查找树,则需要30层)

B+树

1.定义

B+树是在B树的基础上又一次的改进(B树非叶子节点存储数据占用内存,因此进行改进)

B+树与B树的区别:

(1)非叶结点仅具有索引作用,也就是说,非叶子结点只存储key,不存储value

(2)树的所有叶结点构成一个有序链表,可以按照key排序的次序遍历全部数据。

在这里插入图片描述
其中Max Degree=3

2.应用

B+树的优点:
(1)由于B+树在非叶子结点上不包含真正的数据,只当做索引使用,因此在内存相同的情况下,能够存放更多的key。
(2)B+树的叶子结点都是相连的,因此对整棵树的遍历只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。

参考链接:

https://www.bilibili.com/video/BV1rB4y1Q7e6/spm_id_from=333.788&vd_source=752a4cd440b20a1953dc8d254ef99696
https://www.bilibili.com/video/BV1iJ411E7xWp=135&vd_source=38cb30e60861b967d6cdfa51ce1c31fa

猜你喜欢

转载自blog.csdn.net/ji_meng/article/details/128555067