https://blog.csdn.net/qq_35008624/article/details/81947773

仅仅从查找效率来考虑,下面的结论是明显的:
树越矮,查找次数越少,但在每一层所做的工作越多;
树越高,查找次数越多,但在每一层所做的工作越少。

二叉查找树

每个结点的值不重复,且左子树<根<右子树
遍历:中序遍历能保证按序输出。
查找:类似二分查找
插入:O(logn)
移除:移除叶子结点
         移除只有左子树的结点
         移除只有右子树的结点
         移除有左右子树的结点

平衡二叉查找树

高度之差的绝对值不超过1
为什么要有平衡二叉树
优化查找,二叉树退化成X斜树 O(logn)->O(n)
失衡和调整导致插入、删除复杂度增加。
https://www.cnblogs.com/zhuwbox/p/3636783.html

2-3树

2-3树是一棵平衡树,但不是二叉平衡树,2-3最终是会自平衡的。每个非叶子节点都有2个或3个子节点。

 

二叉树,50%概率会增加树高                             K越大,树高增加概率越小

二叉查找树是向下生长,而2-3树是向上生长
当2-3的根节点由3树生长为(红黑树中的旋转)2节点,树的高度增加。

红黑树

https://blog.csdn.net/u013565163/article/details/80820685 必看

红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 
二叉平衡树的严格平衡策略以牺牲建立查找结构(插入,删除操作)的代价,换来了稳定的O(logN) 的查找时间复杂度 
它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。
红黑树属于平衡二叉查找树,高度不要求严格平衡。红黑树其实是2-3树的一种只含2节点的表现形式。我们把2-3树中的2节点用黑色表示,3节点用红色表示(3节点的左节点为黑色、右节点为红色)
定义:
(1) 每个节点或者是黑色,或者是红色。(2-3树节点要么是2节点要么是3节点)
(2) 根节点是黑色。
(3) 每个叶子节点是黑色。 [注意:这里叶子节点,是指为空的叶子节点!]
(4) 如果一个节点是红色的,则它的子节点必须是黑色的。即红色节点不能连续。(红色节点的子和父不能为红)(不能有4节点。注意2-3的4节点是临时的)
(5) 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

性质: 
1>一棵n个结点的AVL树的其高度保持在0(log2(n)),不会超过3/2log2(n+1) 
2>一棵n个结点的AVL树的平均搜索长度保持在0(log2(n)). 
3>一棵n个结点的AVL树删除一个结点做平衡化旋转所需要的时间为0(log2(n)). 

RBT 的操作代价分析: 
(1) 查找代价:由于红黑树的性质(最长路径长度不超过最短路径长度的2倍),可以说明红黑树虽然不像AVL一样是严格平衡的,但平衡性能还是要比BST要好。其查找代价基本维持在O(logN)左右,但在最差情况下(最长路径是最短路径的2倍少1),比AVL要略逊色一点。 
(2) 插入代价:RBT插入结点时,需要旋转操作和变色操作。但由于只需要保证RBT基本平衡就可以了。因此插入结点最多只需要2次旋转,这一点和AVL的插入操作一样。虽然变色操作需要O(logN),但是变色操作十分简单,代价很小。 
(3) 删除代价:RBT的删除操作代价要比AVL要好的多,删除一个结点最多只需要3次旋转操作。 
RBT 效率总结 : 查找 效率最好情况下时间复杂度为O(logN),但在最坏情况下比AVL要差一些,但也远远好于BST。 
插入和删除操作改变树的平衡性的概率要远远小于AVL(RBT不是高度平衡的)。因此需要的旋转操作的可能性要小,而且一旦需要旋转,插入一个结点最多只需要旋转2次,删除最多只需要旋转3次(小于AVL的删除操作所需要的旋转次数)。虽然变色操作的时间复杂度在O(logN),但是实际上,这种操作由于简单所需要的代价很小。

红黑树能够以O(log2(N))的时间复杂度进行搜索、插入、删除操作。此外,任何不平衡都会在3次旋转之内解决。这一点是AVL所不具备的。

插入操作:
1.插入根节点(不需要操作)
2.父节点为黑色(不需要操作)
3.父节点和兄弟节点为红色,祖父节点为黑色,只需要变色,将祖父节点递归检查(原本检查自己)
4.父节点为红色,兄弟节点为黑色,祖父节点为红色,先两次旋转再调整颜色(左旋+右旋)

备注:1.将红黑树当做一颗二叉查找树,将节点插入,新加节点都为红色
2.如果是在黑色节点上添加,则不需要变色;如果是在红色节点上添加,则不满足规则4,需要旋转变色

删除操作:
1.删除只有一个新的根节点(直接删除)
2.父节点为黑色,兄弟节点为红色(先旋转成左左,再删除)
3.父节点为黑色,兄弟节点为黑色(先将兄弟节点换成红色,变成情况2)
4.父节点为红色,自己和兄弟节点为黑色(将父节点变成黑色,兄弟节点变成红色,变成情况2)
5.兄弟节点为黑色,兄弟节点左子树根节点为红色(交换颜色,旋转成为左左)
6.情况2和情况5,调整性质5(将N删掉,用子节点顶替,若子节点为红色,则重绘为黑色)

1. 如果插入一个node引起了树的不平衡,AVL和RB-Tree都是最多只需要2次旋转操作,即两者都是O(1);但是在删除node引起树的不平衡时,最坏情况下,AVL需要维护从被删node到root这条路径上所有node的平衡性,因此需要旋转的量级O(logN),而RB-Tree最多只需3次旋转,只需要O(1)的复杂度。2. 其次,AVL的结构相较RB-Tree来说更为平衡,在插入和删除node更容易引起Tree的unbalance,因此在大量数据需要插入或者删除时,AVL需要rebalance的频率会更高。因此,RB-Tree在需要大量插入和删除node的场景下,效率更高。自然,由于AVL高度平衡,因此AVL的search效率更高。3. map的实现只是折衷了两者在search、insert以及delete下的效率。总体来说,RB-tree的统计性能是高于AVL的。

AVL树与红黑树,插入、删除、查找的平均和最坏情况下都是O(logN);但红黑树整体性能更高;
插入时,二者的旋转次数均最多2次;
AVL树插入、删除时都可能引起树的旋转(保持高度平衡);
AVL树删除时,最坏的情况,旋转的量级为O(logN),而红黑树最多只要3次,为O(1)

因此,查询次数远大于修改时,选择AVL;如果查询,修改次数差不多,则选择红黑树。

B 树

就是常说的“B 减树(B- 树)”,又名平衡多路(即不止两个子树)查找树,它和平衡二叉树的不同有这么几点:
平衡二叉树节点最多有两个子树,而 B 树每个节点可以有多个子树,M 阶 B 树表示该树每个节点最多有 M 个子树
平衡二叉树每个节点只有一个数据和两个指向孩子的指针,而 B 树每个中间节点有 k-1 个关键字(可以理解为数据)和 k 个子树( **k 介于阶数 M 和 M/2 之间,M/2 向上取整)
B 树的所有叶子节点都在同一层,并且叶子节点只有关键字,指向孩子的指针为 null

和平衡二叉树相同的点在于:B 树的节点数据大小也是按照左小右大,子树与节点的大小比较决定了子树指针所处位置。

这里写图片描述

特点:

1、关键字集合分布在整棵树中; 
2、任何一个关键字出现且只出现在一个结点中; 
3、搜索有可能在非叶子结点结束; 
4、其搜索性能等价于在关键字全集内做一次二分查找; 
5、自动层次控制; 

可以看作是对2-3查找树的一种扩展,即他允许每个节点有M-1个子节点。
根节点至少有两个子节点
每个节点有M-1个key,并且以升序排列
位于M-1和M key的子节点的值位于M-1 和M key对应的Value之间
其它节点至少有M/2个子节点

m阶B-树 
1) 树中每个结点至多有m个孩子; 
2) 除根结点和叶子结点外,其它每个结点至少有[m/2]个孩子; 
3) 若根结点不是叶子结点,则至少有2个孩子; 
4) 所有叶子结点都出现在同一层,叶子结点不包含任何关键字信息(可以看做是外部接点或查询失败的接点,实际上这些结点不存在,指向这些结点的指针都为null); 
5) 每个非终端结点中包含有n个关键字信息: (n,A0,K1,A1,K2,A2,……,Kn,An)。其中, 
a) Ki (i=1…n)为关键字,且关键字按顺序排序Ki < K(i-1)。 
b) Ai为指向子树根的接点,且指针A(i-1)指向子树种所有结点的关键字均小于Ki,但都大于K(i-1)。 
c) 关键字的个数n必须满足: [m/2]-1 <= n <= m-1 
建立 
由于B~树结点中的关键字个数必须>=[m/2]-1。因此和平衡二叉树不同,每一次插入一个关键字并不是在树中添加一个结点,而是首先在最低层的某个非终端结点中添加一个关键字,若该结点的关键字个数不超过m-1,则插入完成。否则,要产生结点的”分裂” 。 
外存 
我们现在把整棵树构造在磁盘中,假如每个盘块可以正好存放一个B~树的结点(正好存放2个文件名)。那么一个BTNode结点就代表一个盘块,而子树指针就是存放另外一个盘块 (详细见《外部存储器—磁盘 》)的地址。 
现在我们模拟查找文件29的过程: 
(1) 根据根结点指针找到文件目录的根磁盘块1,将其中的信息导入内存。【磁盘IO操作1次】 
(2) 此时内存中有两个文件名17,35和三个存储其他磁盘页面地址的数据。根据算法我们发现17<29<35,因此我们找到指针p2。 
(3) 根据p2指针,我们定位到磁盘块3,并将其中的信息导入内存。【磁盘IO操作2次】 
(4) 此时内存中有两个文件名26,30和三个存储其他磁盘页面地址的数据。根据算法我们发现26<29<30,因此我们找到指针p2。 
(5) 根据p2指针,我们定位到磁盘块8,并将其中的信息导入内存。【磁盘IO操作3次】 
(6) 此时内存中有两个文件名28,29。根据算法我们查找到文件29,并定位了该文件内存的磁盘地址。

  分析一下上面的过程,我们发现需要3次磁盘IO操作和3次内存查找操作。关于内存中的文件名查找,由于是一个有序表结构,可以利用折半查找提高效率。至于3次磁盘IO操作时影响整个B~树查找效率的决定因素。
  当然,如果我们使用平衡二叉树的磁盘存储结构来进行查找,磁盘IO操作最少4次,最多5次。而且文件越多,B~树比平衡二叉树所用的磁盘IO操作次数将越少,效率也越高。

B+树

特征
有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点
节点的子树数和关键字数相同(B 树是关键字数比子树数少一)
节点的关键字表示的是子树中的最大数,在子树中同样含有这个数据
叶子节点包含了全部数据,同时符合左小右大的顺序(叶子节点用指针连在一起)
优势
单一节点存储更多的元素,层次更低,使得查询的IO次数更少。
所有查询都要查找到叶子节点,查询性能稳定。
所有叶子节点形成有序链表,便于范围查询

这里写图片描述

B*树

是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针。
B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代替B+树的1/2);
B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;
 B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针;

这里写图片描述

LSM-TREE

Log-structured merge-tree

为什么说B+树比B 树更适合实际应用中操作系统的文件索引和数据库索引?

B+树的磁盘读写代价更低 
B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。 
举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B-tree(一个结点最多8个关键字)的内部结点需要2个盘快。而B+树内部结点只需要1个盘快。当需要把内部结点读入内存中的时候,B 树就比B+树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。

B+树的查询效率更加稳定 
由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

B+树和B-树的区别

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

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

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

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

  4. 4.为所有叶子结点增加一个链指针;

  5. 5.所有关键字都在叶子结点出现;

B-树 
性质:是一种多路搜索树(并不是二叉的): 

  1. 1.定义任意非叶子结点最多只有M个儿子;且M>2;

  2. 2.根结点的儿子数为[2, M];

  3. 3.除根结点以外的非叶子结点的儿子数为[M/2, M];

  4. 4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)

  5. 5.非叶子结点的关键字个数=指向儿子的指针个数-1;

  6. 6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];

  7. 7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;

  8. 8.所有叶子结点位于同一层;

  •  

红黑树和平衡二叉树区别如下: 
1、红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单。 
2、平衡二叉树追求绝对平衡,条件比较苛刻,实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能预知。

小结

B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3;

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值