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/ 一. ...
随机推荐
- 前端基础-BOM和DOM的介绍
阅读目录 BOM和DOM的简述 DOM详细操作 事件 一.BOM和DOM的简述 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我 ...
- #leetcode刷题之路24-两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表.你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示例:给定 1->2->3->4, 你应该返回 2-> ...
- luogu11月月赛T3咕咕咕(组合数学)
题目描述 小 F 是一个能鸽善鹉的同学,他经常把事情拖到最后一天才去做,导致他的某些日子总是非常匆忙. 比如,时间回溯到了 2018 年 11 月 3 日.小 F 望着自己的任务清单: 看 iG 夺冠 ...
- thinkphp5.1 学习笔记 【多态关联】
$result = Draft::update($input, ['id' => $input['id']], true); if (!empty(array_get($input, 'hous ...
- 延迟加载图片控件--echo.js
echo.js的github地址:https://github.com/toddmotto/echo echo是一个独立的JavaScript.轻量级的.延迟图片加载插件,echo压缩后体积不到1 ...
- Delphi跨平台下的GetTickCount,GetCurrentThreadID
在Windows下只要uses Windows,就有这两个API可调用GetTickCount,GetCurrentThreadID 如果我们需要跨平台使用这两个函数,就不能仅仅Uses Window ...
- helpera64开机bootlogo-BUG
环境: HelperA64开发板 Linux3.10内核 时间:2019.01.12 目标:修改开机bootlogo的BUG 问题: 1.24bit深度的bootlogo.bmp图片会导致Qt5有色差 ...
- 快速认识LinkIt 7697开发板
LinkIt 7697是一款多功能且价格亲民的开发板,可用来连接网络或你的各项装置,同时提供Wi-Fi及蓝芽两种联机功能.此开发板采用MediaTek MT7697芯片,比起其他类似的Wi-Fi/蓝芽 ...
- Java ArrayList 源代码分析
Java ArrayList 之前曾经参考 数据结构与算法这本书写过ArrayList的demo,本来以为实现起来都差不多,今天抽空看了下jdk中的ArrayList的实现,差距还是很大啊 首先看一下 ...
- Flex4中的拖动技术
下面列一个最简单的例子,在Flex中,拖动原来如此简单 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?xm ...