为什么要有AVL树
- 当出现极端的情况,树的节点可能会近似与链表的形式,使得时间复杂度近似与 O(n)
AVL的旋转有哪几种?
- 左左型 :节点都偏向左边
- 顺时针旋转两个节点,使得自己的左子节点成为根节点,而自己成为右子节点
- 右右型:节点都偏向右边
- 逆时针旋转两个节点,使得自己的右子节点成为根节点,而自己成为左子节点
- 右左型:节点是偏向右边,但是最底下的叶节点偏向左边
- 将它转化为右右型号
- 再进行右右型的旋转
- 左右型:节点是偏向左边,但是最底下的爷节点是偏向右边
- 将他转化为左左型号
- 再进行左左型的旋转
为什么有了平衡树还要有红黑树
- 平衡树解决了在极端的情况下变成链表的情形,使得任意的两个叶子节点的深度小于等于1。
- 这个要求是在是太严格了,基本上每次新增插入,或者是删除的时候,都会破坏这个要求
- 使得每次都要进行左旋或者是右旋来调整,进而成为一颗平衡二叉树
- 如果是在删除,插入场景很多的情况下,AVL树的性能会大大的折扣
红黑树的特点
- 是一种二叉搜索树,任意的左子节点都比自己小,右子节点都比自己大
- 根节点是黑色的
- 每个叶子节点都是黑色的,并且里面不存数据,为空
- 任意两个相邻的节点不能是红色的,也就是,红节点是被黑节点分割开来
- 每个节点,从该节点到其可达的叶子节点的所有路劲,都包括相同数量的黑色节点
B 树
- 每个节点中都存放着信息,所以查询的时候,最快为O(1),最多为O(log n)
- 他的叶节点没有指针进行相连,不适合与范围查询
B+ 树
- B+ 树是为了磁盘设计的一种平衡查找树,所以的数据节点都放在同一层的叶节点中,并且各个叶节点有指针连接
- 有K个字数的节点就含有K 个元素,每个元素不放数据,只放索引,数据统一放在叶节点之中
- 所有的叶节点包含了全部的数据信息,以及指向数据的指针,并且数据是按照从小到大依次进行排列的。
- 所有的中间节点都同时存在于子节点中,在子节点是最大,最小元素
- B+ 树是从下到上查找,而B 树是从下到上查找
- 单一节点存储更多的元素,使得树变得矮胖了,树下的分支变多了,减少I/O 的次数
- 所有的查询都要查询到叶子节点,查询性能稳定
- 所有的叶子节点都是按序连接的,适合与范围查询
1:treenode
- treenode 是继承了node结构,在node基础上加了几个字段
- 指向父节点的,指向左子节点,指向右子节点,还有表示颜色的
2:插入
- 找到一个合适的插入点,就是找到插入节点的父节点,红黑树满足二叉搜索树的特性,需要进行一次的平衡操作
- 插入会打破平衡
- 插入一定是红色的节点,碰到父节点是黑色的,树不会失衡
3:扩容
- treenode保持着一个 next的字段,查询的时候不适用
- 但是新增或者是删除节点的时候,仍然需要维护这个链表
- 链表方便split拆分这个红黑树的时候,拆分为高位链和地位链
- 高位链的数据,最重要存放到新表中去
- 拆分出来的链表,需要看一下他的长度
B+ 树索引和 B树索引
- 由于关系型数据库和非关系型数据库数据设计方式的不同,导致关系型数据库常常用到数据的遍历,而非关系型用到表的单一查询
- 所以在MySQL 数据库中,使用B+ 树作为索引,而在mongodb中,B 树作为索引