B树(B-树)、B+树、AVL树、B*树

看数据结构的时候经常容易被各种树绕晕,所以重新整理下这些 纠结树。

 

1,B树(B-树)

 注意,好多地方都喜欢说B-树,给人一种错觉B-树与B树是两种数据结构,其实是一种。

外文翻译的时候B-tree,有的人喜欢翻译成B-树,有的翻译为B树,所以才造成了这样的错觉。

先看看B树的数据结构:

 

这是从july算法的博客中拿过来的一个图

 

定义为:

     一颗m阶的B树是一颗平衡的m路搜索树,它或者为空树,或者满足下列条件:

    1,每个结点最多有m个孩子

    2,除根结点外,每个非叶子结点至少有[ceil(m/2)]个孩子结点,ceil(表示向上取整)

   3,若根节点不是叶子结点,则它至少有2个孩子。

   4,有k个孩子的非叶子结点恰好有k-1个关键码,关键码按递增次序排列。

  5,所有的叶子结点都在同一层。B树的叶子结点可以看作一种外部结点,不包含任何信息

 

维基百科的定义:

 

  B树的高度:

        若B树某一非叶子节点包含N个关键字,则此非叶子节点含有N+1个孩子结点,而所有的叶子结点都在第K层,我们可以得出

      1,因为根节点至少有2个孩子,所以第2层至少有2个结点

      2,除根和叶子结点外,其他结点至少有[ceil(m/2)]个孩子,ceil()向上取整

      3,第三层至少有2*[ceil(m/2)]个孩子

      4,第四层至少有2*[ceil(m/2)^2]个孩子

      5 ,第K层至少有2*[ceil(m/2)^(k-2)]个孩子,则N+1>=2*[ceil(m/2)^(k-2)]

     6,考虑第K层的结点个数为N+1,那么2*[ceil(m/2)^(k-2)]<=N+1,也就是k层的最少结点数刚好达到N+1个,即: K≤ log┌m/2┐((N+1)/2 )+2;

 

所以当B树包含N个关键字时,B树的最大高度为K-1(因为计算B树高度时,叶结点所在层不计算在内),即:K - 1 =  log┌m/2┐((N+1)/2 )+1
 
 
 
2,B+树
B+树是应 文件系统所需而出的一种 B-树的变型树。一棵m阶的B+树和m阶的B-树的差异在于:
 

       一棵m阶的B+树和m阶的B树的异同点在于:

      1.n棵子树的结点中含有n-1 个关键字; (此处颇有争议,B+树到底是与B 树n棵子树有n-1个关键字 保持一致,还是不一致:B树n棵子树的结点中含有n个关键字,待后续查证。暂先提供两个参考链接:①wikipedia http://en.wikipedia.org/wiki/B%2B_tree#Overview;②http://hedengcheng.com/?p=525。而下面B+树的图尚未最终确定是否有问题,请读者注意)

      2.所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接。 (而B 树的叶子节点并没有包括全部需要查找的信息)

      3.所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息)

 

 

B+树是B-树的变体,也是一种多路搜索树:

其定义基本与B-树同,除了:

1).非叶子结点的子树指针与关键字个数相同

2).非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);

3).为所有叶子结点增加一个链指针

4).所有关键字都在叶子结点出现

为了全面 这里给出网上另外一种说法:

一棵m阶的B+树和m阶的B树的差异在于:

      1.有n棵子树的结点中含有n个关键字; (而B 树是n棵子树有n-1个关键字)

      2.所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接。 (而B 树的叶子节点并没有包括全部需要查找的信息)

      3.所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息)

下图给出典型的3阶B+树示例

 

B+的特性:

1).所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

2).不可能在非叶子结点命中;

3).非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;

4).更适合文件索引系统;

 

 

 
uploading.4e448015.gif转存失败重新上传取消

 

uploading.4e448015.gif转存失败重新上传取消

 

 

uploading.4e448015.gif转存失败重新上传取消3,B*树

 

B*Tree是B+树的变体,在B+Tree的非根和非叶子结点(内结点)再增加指向兄弟的指针

B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代替B+树的1/2);

B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;

B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针

所以,B*树分配新结点的概率比B+树要低,空间使用率更高。

 

uploading.4e448015.gif转存失败重新上传取消4,AVL树

 

1. 概述

 

AVL树是最早提出的自平衡二叉树,在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。AVL树得名于它的发明者G.M. Adelson-Velsky和E.M. Landis。AVL树种查找、插入和删除在平均和最坏情况下都是O(log n),增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。本文介绍了AVL树的设计思想和基本操作。

2. 基本术语

有四种种情况可能导致二叉查找树不平衡,分别为:

(1)LL:插入一个新节点到根节点的左子树(Left)的左子树(Left),导致根节点的平衡因子由1变为2

(2)RR:插入一个新节点到根节点的右子树(Right)的右子树(Right),导致根节点的平衡因子由-1变为-2

(3)LR:插入一个新节点到根节点的左子树(Left)的右子树(Right),导致根节点的平衡因子由1变为2

(4)RL:插入一个新节点到根节点的右子树(Right)的左子树(Left),导致根节点的平衡因子由-1变为-2

针对四种种情况可能导致的不平衡,可以通过旋转使之变平衡。有两种基本的旋转:

(1)左旋转:将根节点旋转到(根节点的)右孩子的左孩子位置

(2)右旋转:将根节点旋转到(根节点的)左孩子的右孩子位置

3. AVL树的旋转操作

AVL树的基本操作是旋转,有四种旋转方式,分别为:左旋转,右旋转,左右旋转(先左后右),右左旋转(先右后左),实际上,这四种旋转操作两两对称,因而也可以说成两类旋转操作。

3.1 LL

LL情况需要右旋解决,如下图所示:

LL.jpguploading.4e448015.gif转存失败重新上传取消

3.2 RR

RR情况需要左旋解决,如下图所示:

RR.jpguploading.4e448015.gif转存失败重新上传取消

代码为:

3.3 LR

LR情况需要左右(先B左旋转,后A右旋转)旋解决,如下图所示:

LR.jpguploading.4e448015.gif转存失败重新上传取消

 

 

3.4 RL

RL情况需要右左旋解决(先B右旋转,后A左旋转),如下图所示:

RL.jpguploading.4e448015.gif转存失败重新上传取消

 

5 红黑树

每个节点要么是红色,要么是黑色;

  1. 根节点永远是黑色的;
  2. 所有的叶节点都是是黑色的(注意这里说叶子节点其实是上图中的 NIL 节点);
  3. 每个红色节点的两个子节点一定都是黑色;
  4. 从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值