7. B+树
一、B+树是应文件系统所需而产生的一种B树的变形树
1. 定义(使用阶数m来定义)
- 除了根结点外,其他非终端结点最多有m个关键字,最少有⌈m/2⌉个关键字
- 结点中的每个关键字对应一个子树
- 所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字
所有的叶子节点包含了全部的关键字以及指向含有这些关键字记录的指针,并且:
- 同一叶子节点中的关键字按大小顺序排列
- 相邻的叶子节点顺序链接(相当于是构成了一个顺序链表)
- 所有叶子节点在同一层

2. 和B树的区别
对于非终端结点,关键字的个数与其子树的个数相同;不像B树,子树的个数总比关键字的个数多1。
所有的关键字及相应的指针都在叶子结点中;不像B树,有的关键字是在内部结点中。(换句话说,在B+树中,内部结点仅仅起到索引的作用。在搜索过程中,如果待查询的关键字和内部结点的关键字一致,那么搜索过程不停止,而是继续向下搜索这个分支)
- 关键字的数量不同:B+树中,对于非终端结点,关键字的个数与其子树的个数相同;而B树中,关键字的个数比子树的个数少1。
- 存储的位置不同:B+树中的数据都存储在叶子结点上,也就是其所有叶子结点的数据组合起来就是完整的数据;而B树的数据存储在每一个结点中。
- 非终端结点的构造不同:B+树的非终端结点仅仅存储着关键字信息和指向孩子的指针(这里的指针指的是磁盘块的偏移量),也就是说内部结点仅仅包含着索引信息。
- 查询不同:B树在找到具体的数值以后,则结束;而B+树则需要通过索引找到叶子结点中的数据才结束,也就是说B+树的搜索过程中走了一条从根结点到叶子结点的路径。
二、关于B+树的面试题
1. 为何B+树用于数据库索引?
B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B树的其非终端结点同样存储着数据,因此如果我们要找到具体的数据,就需要进行一次中序遍历。正是为了解决这个问题,B+树应运而生。
B+树的数据都存储在叶子结点中,非终端结点均为索引,方便扫库,只需要遍历叶子结点即可实现整棵树的遍历。所以B+树更加适合在区间查询的情况,而且在数据库中基于范围的查询是非常频繁的,所以通常B+树用于数据库索引。
2. 为何相比于B树,B+树在文件系统和数据库系统中更具优势?
①B+树的磁盘读写代价更低
B+树的非终端结点并没有指向关键字具体信息的指针,因此其内部结点相对B树更小。如果把同一非终端结点的所有关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说I/O读写次数也就降低了。
举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B树(一个结点最多8个关键字)的非终端结点需要2个盘快。而B+树非终端结点只需要1个盘快。当需要把非终端结点读入内存中的时候,B树就比B+树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。
②B+树的查询效率更加稳定
由于非终端结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路径。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
③B+树更有利于对数据库的扫描
B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题,而B+树只需要遍历叶子节点就可以解决对全部关键字信息的扫描,所以对于数据库中频繁使用的范围查询,B+树有着更高的性能。
7. B+树的更多相关文章
- B树——算法导论(25)
B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...
- ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单
前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- HDU1671——前缀树的一点感触
题目http://acm.hdu.edu.cn/showproblem.php?pid=1671 题目本身不难,一棵前缀树OK,但是前两次提交都没有成功. 第一次Memory Limit Exceed ...
- 算法与数据结构(十一) 平衡二叉树(AVL树)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- bzoj3207--Hash+主席树
题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...
- bzoj1901--树状数组套主席树
树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...
- bzoj3932--可持久化线段树
题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...
- jquery-treegrid树状表格的使用(.Net平台)
上一篇介绍了DataTable,这一篇在DT的基础之上再使用jquery的一款插件:treegrid,官网地址:http://maxazan.github.io/jquery-treegrid/ 一. ...
随机推荐
- GoogleTest初探(2)
前面的随笔介绍了Google Test中的基本测试单元TEST和测试夹具TEST_F,此篇介绍区别于这两种测试的参数化测试TEST_P 当待测试方法的行为取决于传入的参数时,而且这些参数的不同组合有多 ...
- 微信JSSDK的使用
微信JS-SDK 1.在微信公众平台(https://mp.weixin.qq.com/)注册个公众号,获取APPID和AppSecret 2.获取access_token(需要在公众平台中设置获取a ...
- ansible常用配置
1.什么是Ansible 部署参考连接:http://www.ansible.com.cn/ ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfeng ...
- Django学习笔记6(iframe、外键插入)
1.{%include 'index.html'%i} 平时很好用的iframe在django里面的不是很好用 django里面提供了{%include 'index.html'%i}的方式来取代了i ...
- rpm与yum,at与crontab,sed命令使用
1.简述rpm与yum命令的常见选项,并举例. rpm——软件包管理系统,它使得在Linux下安装.升级.删除软件包的工作变得容易,并且具有查询.验证软件包的功能. 1)安装选项 命令格式: rpm ...
- Uncaught SyntaxError: Unexpected token : 开发遇到的跨域问题
先描述一下,这个问题,是如何遇到的 在ajax调用远程服务的时候,报了一个Origin xxxxxx is not allowed by Access-Control-Allow-Origin 的错误 ...
- jquery 60s倒计时
前端开发中经常用到的发送按钮倒计时,每次都是重写,挺麻烦的,记录一下,以后直接来复制代码 <!DOCTYPE html> <html> <head> <met ...
- 在mac上使用tar.gz安装mysql
官方: download: https://dev.mysql.com/downloads/mysql/ mysql参考文档:https://dev.mysql.com/doc/ 环境: macOS ...
- HTML5 添加视频和音频(响应式视频)
最初的 HTML5规范呼吁所有浏览器内置支持使用 Ogg格式① 直接播放视频或音频(无需插件).但是由于 HTML5工作组的内部争议,曾经作为基线标准的支持 Ogg(包括 Theoravideo 和 ...
- js对字符串进行加密和解密
//字符串进行加密 function compileStr(code){ var c=String.fromCharCode(code.charCodeAt(0)+code.length); fo ...