数据结构-满二叉树-完全二叉树-完美二叉树-二叉查找树-AVL树-红黑树-B/B+树

一、满二叉树(Full Binary Tree

每个结点有0个或者2个孩子,即除了叶子结点外,所有结点都有2个孩子。

满二叉树举例:

二、完全二叉树(Complete Binary Tree

完全二叉树的每层结点完全填满,最后一层可以不满,若不满时只能缺少右边的若干结点,即结点全部集中在左侧。

完全二叉树举例:

 

三、完美二叉树(Perfect Binary Tree)

所有的 internal nodes(内部结点)都有2个孩子,所有的叶子结点都在同一层。

internal nodes介绍:

完美二叉树举例:

高度为h的完美二叉树的结点总数为:2^{h} – 1。(高度h是从根结点到叶子结点的层数)

 

四、二叉查找树(Binary Search Tree)

1 简介

二叉查找树也称为有序二叉查找树,满足二叉查找树的一般性质,是指一棵空树具有如下性质:

  • 任意节点左子树不为空,则左子树的值均小于根节点的值;

  • 任意节点右子树不为空,则右子树的值均大于于根节点的值;

  • 任意节点的左右子树也分别是二叉查找树;

  • 没有键值相等的节点。

注意,二叉查找树的中序遍历一定是从小到大的。

二叉查找树举例:

200px-Binary_search_tree.svg

 

2 局限性

一个二叉查找树是由n个节点随机构成,所以,对于某些情况,二叉查找树会退化成一个有n个节点的线性链。如果我们的根节点选择是最小或者最大的数,那么二叉查找树就完全退化成了线性结构。

 

 

五、AVL树

1 简介

AVL树是带有平衡条件的二叉查找树,一般是用平衡因子差值判断是否平衡并通过旋转来实现平衡,左右子树树高不超过1,和红黑树相比,它是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1)。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入删除次数比较少,但查找多的情况。

AVL树举例:


 

2 局限性

由于维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。当然,如果应用场景中对插入删除不频繁,只是对查找要求较高,那么AVL还是较优于红黑树。

3 应用

Windows NT内核中广泛存在。

六、红黑树

1 简介

一种二叉查找树,但在每个节点增加一个存储位表示节点的颜色,可以是red或black。 通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有一条路径会比其它路径长出两倍。它是一种弱平衡二叉树(由于是弱平衡,可以推出,相同的节点情况下,AVL树的高度低于红黑树),相对于要求严格的AVL树来说,它的旋转次数变少,所以对于搜索,插入,删除操作多的情况下,我们就用红黑树。

2 性质

  • 每个节点非红即黑;

  • 根节点是黑的;

  • 每个叶节点(叶节点即树尾端NUL指针或NULL节点)都是黑的;

  • 如果一个节点是红的,那么它的两儿子都是黑的;

  • 对于任意节点而言,其到叶子点树NIL指针的每条路径都包含相同数目的黑节点;

  • 每条路径都包含相同的黑节点;

è¿éåå¾çæè¿°

3 应用

  • 广泛用于C++的STL中,map和set都是用红黑树实现的。

  • 著名的linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块,进程的虚拟内存区域都存储在一棵红黑树上,每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址虚拟存储区域,右指针指向相邻的高地址虚拟地址空间。

  • IO多路复用epoll的实现采用红黑树组织管理sockfd,以支持快速的增删改查。

  • ngnix中,用红黑树管理timer,因为红黑树是有序的,可以很快的得到距离当前最小的定时器。

  • java中TreeMap的实现。

七、B/B+树

1 简介

B/B+树是为了磁盘或其它存储设备而设计的一种平衡多路查找树(相对于二叉,B树每个内节点有多个分支),与红黑树相比,在相同的的节点的情况下,一颗B/B+树的高度远远小于红黑树的高度(在下面B/B+树的性能分析中会提到)。B/B+树上操作的时间通常由存取磁盘的时间和CPU计算时间这两部分构成,而CPU的速度非常快,所以B树的操作效率取决于访问磁盘的次数,关键字总数相同的情况下B树的高度越小,磁盘I/O所花的时间越少。

2 B树的性质

  • 定义任意非叶子节点最多只有M个儿子;且M>2;

  • 根节点的儿子数为[2, M];

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

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

  • 非叶子节点的关键字个数=指向儿子的指针个数-1;

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

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

  • 所有叶子节点位于同一层;

è¿éåå¾çæè¿°

这里只是一个简单的B树,在实际中B树节点中关键字很多的。上面的图中比如35节点,35代表一个key(索引),而小黑块代表的是这个key所指向的内容在内存中实际的存储位置,是一个指针。

3 B+树

B+树是应文件系统所需而产生的一种B树的变形树(文件的目录一级一级索引,只有最底层的叶子节点(文件)保存数据),非叶子节点只保存索引,不保存实际的数据,数据都保存在叶子节点中。这不就是文件系统文件的查找吗?我们就举个文件查找的例子:有3个文件夹,a,b,c,a包含b,b包含c,一个文件yang.c。 a,b,c就是索引(存储在非叶子节点), a,b,c只是要找到的yang.c的key,而实际的数据yang.c存储在叶子节点上。 所有的非叶子节点都可以看成索引部分。

4 B+树的性质

下面提到的都是和B树不相同的性质:

  • 非叶子节点的子树指针与关键字个数相同;

  • 非叶子节点的子树指针p[i],指向关键字值属于[k[i],k[i+1]]的子树。(B树是开区间,也就是说B树不允许关键字重复,B+树允许重复);

  • 为所有叶子节点增加一个链指针。

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

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

  • 更适合于文件系统; 看下图:

è¿éåå¾çæè¿°

非叶子节点(比如5,28,65)只是一个key(索引),实际的数据存在叶子节点上(5,8,9)才是真正的数据或指向真实数据的指针。

5 应用  

B和B+树主要用在文件系统以及数据库做索引,比如Mysql。

6 B/B+树性能分析 

  • n个节点的平衡二叉树的高度为H(即logn),而n个节点的B/B+树的高度为logt((n+1)/2)+1;   

  • 若要作为内存中的查找表,B树却不一定比平衡二叉树好,尤其当m较大时更是如此.因为查找操作CPU的时间在B-树上是O(mlogtn)=O(lgn(m/lgt)),而m/lgt>1;所以m较大时O(mlogtn)比平衡二叉树的操作时间大得多. 因此在内存中使用B树必须取较小的m.(通常取最小值m=3,此时B-树中每个内部结点可以有2或3个孩子,这种3阶的B-树称为2-3树)。

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

  • B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。

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

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

7 B树和B+树的区别

img

 

如图所示,区别有以下两点:

  • B+树中只有叶子节点会带有指向记录的指针(ROWID),而B树则所有节点都带有,在内部节点出现的索引项不会再出现在叶子节点中。

  • B+树中所有叶子节点都是通过指针连接在一起,而B树不会。

 

B+树的优点:

  • 非叶子节点不会带上ROWID,这样,一个块中可以容纳更多的索引项,一是可以降低树的高度。二是一个内部节点可以定位更多的叶子节点。

  • 叶子节点之间通过指针来连接,范围扫描将十分简单,而对于B树来说,则需要在叶子节点和内部节点不停的往返移动。

 

B树的优点:对于在内部节点的数据,可直接得到,不必根据叶子节点来定位。

参考文献:

https://blog.csdn.net/whoamiyang/article/details/51926985

https://www.geeksforgeeks.org/binary-tree-data-structure/

https://stackoverflow.com/questions/265809/what-is-an-internal-node-in-a-binary-search-tree

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值