1. 二叉排序树(二叉查找树)
结构特点:左节点值小于父节点,右节点值大于父节点
目的:提高增、查效率
{62,88,58,47,35,73,51,99,37,93} 排序如下
- 查找
SearchBST(BiTree T, int key, BiTree f, BiTree *p)
假设要查找93
- 93>62,查右子树,走①,递归调用SearchBST函数
- 93>88,查右子树,走⑦,递归调用SearchBST函数
- 93<99,查左子树,走⑨,递归调用SearchBST函数
- 93=93,查找成功
- 插入
InsertBST(BiTree *T, int key)
假设要插入95
- 先查找,直到95>93,发现查找失败,开始执行插入操作
- 因为95>93,插入为93的右子节点
- 删除
DeleteBST(BiTree *T, int key)
叶子节点可以直接删除
只有左子树或右子树的节点删除后,连接其子节点和父节点即可
左子树和右子树都有的节点,假设要删除47
- 查找47的左子树最后的右节点37,替换47为37
- 删除原来的37,连接其子节点和父节点
具体Java代码实现参考 https://www.cnblogs.com/yandufeng/p/10845118.html
2. 平衡二叉树(AVL树)
结构特点:左子树和右子树的深度之差(即平衡因子BF)的绝对值不超过1
构建过程:每当插入新元素导致出现最小不平衡子树,旋转调整为平衡再继续插入
旋转规则:BF≥2,右旋;BF≤-2,左旋
- 右旋:左子节点绕父节点顺时针转90°
- 左旋:右子节点绕父节点逆时针转90°
插入新元素后,BF符号相同,右旋(左旋)一次:
BF符号不同时,先左旋再右旋(先右旋再左旋):
3. 多路查找树(B树)
B树的阶:节点的孩子数量的最大值
结构特点:
- 是平衡的,节点的孩子数可以多于2个
- 每个节点存储的元素,包含n+1个指针、n个关键字,n为关键字数量
- 所有的叶子节点在同一层
- m阶B树,至少有2*ceil(m/2)^h-1个节点,每个节点至少有ceil(m/2)-1个关键字
B树的结点不仅存储关键字,还存储关键字对应的记录的data值。而磁盘每一页的存储空间是有限的,16k,如果data数据较大时将会导致每个结点能存储的key数量很小,当存储的数据量很大时同样会导致B树的高度很大,增大查询是的磁盘IO次数,进而影响查询效率(主存和磁盘以页为单位交换数据,B+树将每个节点的大小设置和页大小一样,都为16K,因此读取一个节点,只需要一次IO)
而B+树中,所有数据节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息, 这样可以大大加大每个节点存储的key值数量, 降低B+树的高度,减少查询时的IO次数。
4. B+树
B+树是应文件系统所需而出的一种B树的变形树
结构特点:
- B树的基础上,存在叶子节点元素在头部或尾部保存父节点元素的关键字
- 叶子节点保存了指向下一叶子节点的指针
- 所有叶子节点从小到大顺序链接,且包含了所有关键字信息
插入
B树插入,B+树同理:
删除
B树删除,B+树同理
分裂时需注意
- 叶子结点的分裂,是拷贝中间值,再合并到索引结点,原位key值不变
- 非叶子结点分裂时,直接提取中间值合并到索引结点
- 分裂后每个结点的key个数不能低于50%