二叉搜索树、AVL树、红黑树、B树、B+树

文章目录

    • 1. 二叉搜索树
      • 1.1 概念
      • 1.2 插入
      • 1.3 删除
      • 1.4 时间复杂度
    • 2. AVL树
      • 2.1 插入
      • 2.2 时间复杂度
    • 3. 红黑树
    • 4. B树
      • 4.1 时间复杂度
    • 5. B+树
      • 5.1 B树和B+树的区别
    • MyISAM
    • InnoDB

1. 二叉搜索树

1.1 概念

二叉搜索树又称二叉排序树
规则:

  • 若它的左子树不为空,则左子树上的所有节点的值都小于根节点的值
  • 若它的右子树不为空,则右子树上的所有节点的值都大于根节点的值
  • 它的左右子树也是二叉搜索树
    二叉搜索树、AVL树、红黑树、B树、B+树_第1张图片

1.2 插入

插入是根据二叉搜索树的特性,左边的子树都比根小右边的子树都比根大
二叉搜索树、AVL树、红黑树、B树、B+树_第2张图片
二叉搜索树、AVL树、红黑树、B树、B+树_第3张图片

1.3 删除

二叉搜索树、AVL树、红黑树、B树、B+树_第4张图片
二叉搜索树、AVL树、红黑树、B树、B+树_第5张图片
二叉搜索树、AVL树、红黑树、B树、B+树_第6张图片
综上所述,删除规则为:

  • 左为空,父亲指向我的右
  • 右为空,父亲指向我的左
  • 左右均不为空,替换法删除

1.4 时间复杂度

虽然说二叉搜索树是树的形式,时间复杂度应该是O(logN)但是二叉搜索树有一种极端的情况
比如说:
二叉搜索树、AVL树、红黑树、B树、B+树_第7张图片
所以二叉搜索树的时间复杂度为O(n)
由于在这种情况下,二叉搜索树会退化为链表,性能大大降低,为避免这种问题的出现引出了AVL树

2. AVL树

AVL树为高度平衡的二叉搜索树
每个结点的左右子树的高度差不超过1
二叉搜索树、AVL树、红黑树、B树、B+树_第8张图片

2.1 插入

AVL也是二叉搜索树,所以增加和删除和二叉搜索树是一样的操作,假如说对于1,2,3,4,5,用单纯的二叉搜索树操作,这颗树就会退化成链表,而AVL会对这些树进行旋转操作来达到平衡

2.2 时间复杂度

由于AVL树不会出现单支树的情况,并且左右子树的高度差不超过1,要想查找一个结点,最多就是查找树的高度次
我们可以近似求得树的高度为logN
所以AVL树的时间复杂度为O(logN)

3. 红黑树

性质:

  • 每个结点不是红色就是黑色
  • 根节点是黑色
  • 如果一个节点是红色,则它的两个孩子是黑色(没有连续的红)
  • 对于每个结点从该结点到其后代结点的路径上,均包含相同数目的黑色结点

红黑树:最长路径不超过最短路径的2倍

二叉搜索树、AVL树、红黑树、B树、B+树_第9张图片

为什么有了AVL还需要有红黑树?
红黑树并没有像AVL树那样追求平衡,但相对于AVL来说红黑树的旋转操作会少很多,所以红黑树适合增删多的场景,AVL树适合查找多的场景

4. B树

如果一颗B树有M阶(每个节点至多有M个孩子):

  • 根节点至少有两个孩子
  • 每个非根结点至少有M/2-1个关键字,至多有M-1个关键字,并且以升序排列
  • 每个非根结点至少有M/2个孩子,至多有M个孩子
  • key[i]和key[i+1]之间孩子结点的值介于key[i]和key[i+1]之间

为什么非根结点至少有M/2-1个关键字?
当结点的个数为偶数,分裂成两个时,要向上提取一个值,其中有一个孩子必定比另一个孩子的结点数少1;

B树有什么用?
B树大多用在磁盘上用于查找磁盘的数据,因为磁盘有大量的数据,没有办法一次性加入到内存中,只能逐一加载磁盘页,每个磁盘页 对应一个结点,对于B树来说,B树很好的将树的高度降低了,这样会减少IO查询次数,虽然一次加载到内存的数据变多了,但速度优于AVL树或红黑树。

4.1 时间复杂度

由于孩子的数量总是比关键字多一个
如果是M阶的B树
第一层: M-1 (M-1个关键字)
第二层:M* (M-1) (M个孩子* 每个孩子M-1个关键字)
第三层: M * M * (M-1) (上层关键字是M-1个,所以这层有M个孩子上层M个孩子每个孩子M个关键字)
……
将每层的M-1近似替换为M
所以M*M2*M3……*Mh = N
可以得出时间复杂度为:O(logmN)
假如说节点中关键字每次都存最小的个数,时间复杂度就为O(logm/2N)
综上 B树的时间复杂度为O(logm/2N)~O(logmN)

5. B+树

B+树比起B树多了几条规则

  • 孩子数量跟关键字数量相等
  • 根节点关键字【1,M】孩子数量【M/2,M】
  • 非根节点关键字【M/2,M】,孩子数量【M/2,M】
  • 所有关键字都在叶子结点出现,非叶子结点存的是孩子结点的最小值,仅仅作为索引
  • 只有叶子结点有Data域

5.1 B树和B+树的区别

  • B树的孩子结点总是比关键字多1、B+树的孩子结点和关键字的个数是一样的
  • B树每个结点都存储key和data、但B+树只有叶子结点存储data,叶子节点包含了这棵树的所有键值,并且可以顺序访问

mysql的Innodb引擎为什么采用B+树的索引方式?

为什么不用AVL树和红黑树?
我们假设B+树一个结点可以100个关键字,那么三层的B树可以容纳大概(100+101100+101101*100)个关键字约1000000多个关键字,而红黑树和AVL树要存储这么多元素至少要20层,所以B树相对于红黑树和AVL树可以减少IO操作。
为什么不用哈希表?
虽然哈希表的查询效率很高,但是Innodb的范围查询哈希表无法实现
为什么不用B树?

  • B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。

在MySQL中,最常用的两个存储引擎是MyISAM和InnoDB,它们对索引的实现方式是不同的。

MyISAM

data存的是数据地址。
索引是索引,数据是数据。索引放在XX.MYI文件中,数据放在XX.MYD文件中,所以也叫非聚集索引。
二叉搜索树、AVL树、红黑树、B树、B+树_第10张图片
MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。

InnoDB

data存的是数据本身。索引也是数据。数据和索引存在一个XX.IDB文件中,所以也叫聚集索引。
二叉搜索树、AVL树、红黑树、B树、B+树_第11张图片
InnoDB的数据文件本身就是索引文件。MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而InnoDB索引,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。
如果是辅助索引,辅助索引data域存储相应记录主键的值,所以如果用辅助索引查询,一般得查两次。

你可能感兴趣的:(Java)