B-树(B+树) 学习总结
一,B-树的定义及介绍
为什么会有B-树?
熟悉的树的结构有二叉树查找树或者平衡二叉树……平衡二叉树保证最坏情况下各个操作的时间复杂度为O(logN),但是为了保持平衡,在插入或删除元素时,需要进行旋转啊...一系列操作,因此实现起来比较复杂。而对于二叉查找树,基本操作在最坏情况下会出现O(N)的时间复杂度。总之,这些树都是针对于内存中的数据操作,它们每个结点最多只有两个孩子,当数据量大时(结点数目很多),就会导致树很高。但由于基本操作(查找元素、插入元素)都是在内存中实现,因此,树高点也就没有太大的关系。
试想,如果树中的结点数据 是存储在磁盘上的,每访问一个结点需要进行一次磁盘的读取操作,那么树的高度就很重要了。因为,磁盘访问的代价(速度)远远大于内存访问的代价。对于7200转的硬盘而言,访问一次磁盘大约需要8.3ms,而对于4GHz的CPU而言,8.3ms不知可以执行多少次指令了。
因此,B树一个很重要的特征就是:高度小。
那如何让高度变小呢?让每个结点可以拥有多个(远远大于2)孩子就可以了。但是,为了在插入、删除中仍然保持B树的性质(比如高度要低),还需要对B树做一些其他方面的规定:(实际实现过程中可能不同)。
其中最重要的规定是:每个结点最多包含多少个关键字(项),最少需要包含多少个关键字。
这里,给出一个具体的M阶 B树定义(《数据结构与算法分析》MAW著)
①数据项 只存储在树叶上。(数据项就是实实在在的数据,而不是索引)
②非叶子结点最多可以 存储 M-1个关键字以指示搜索的方向(这里的关键字是指索引)。
这里的M-1个关键字是按从小到大的顺序排序的。M-1个关键字,就有M个指针,指向进一步查找的路径。
③树的根或者是一片树叶,或者其儿子数在 2 到 M之间
④除根外,所有非树叶节点的儿子数在 【M/2】 和 M 之间 【M/2】表示,M/2并向上取整
非叶子结点的儿子数最少为【M/2】,这就是为了保证每个结点足够多的孩子,从而使树的高度不至于太大。
⑤所有的树叶都在相同的深度上并有【L/2】 和 L 个数据项
这里表明,真正的数据只存储在叶子结点上。非叶子结点只存储索引。
在上面的具体规定中,M 和 L 是如何确定的呢?
M 和 L的确定与磁盘块的大小相关。对于B树而言,每个结点都尽量占据一个磁盘块。
比如,假设有 1千万数据项,每个关键字(索引)是32B,而每个数据项是256B,磁盘块的大小是8192B,如何确定M 和 L 呢?
由于M阶B树中,每个结点最多有 M-1 个关键字,故关键字总大小为 32M-32,M-1个关键字最多有M个分支指针,假设每个分支指针是4B(字节),故分支指针的大小是4*M个字节。那么对于一个非叶子结点,它的大小是36*M-32 字节,由于磁盘块大小是8192,故M = 8192/(36*M-32) = 228
(注意:这里的“关键字”其实类似于数据项,待插入的数据项 就是 通过比较关键字 来确定走哪条分支指针)
由上面的第5点可知,叶子结点只存储数据项,每个数据项大小为256B,故 L=8192/256=32,这说明每个叶子结点可以存储32个数据项。
M 与关键字以及指针的大小有关,而L与数据项的大小有关。总之,目标是:不管是叶结点还是非叶结点,都尽量保证一个结点占据一个磁盘块。
二,B树的基本操作
1)查找操作
查找操作的伪代码如下:《算法导论》这里的B树中数据项可存储在非叶子结点上。
B-TREE-SEARCH(x,k)
i =
while i<= M' and k > key(i)
i++
if i<=M' and k=key(i)
return (x,i)
if leaf(x)
return NIL
else
DISK-READ(child(x(i)))
return B-TREE-SEARCH(child(x(i)),k)
x实际上代表根结点。第3行,扫描结点上所有的数据项看是否与k匹配,若不匹配且结点不是叶子结点,则需要在第10行进行一次磁盘读取操作,将该结点中某数据项指向的孩子结点读入内存,再进行比较。
2)插入操作
插入操作可能会导致结点分裂。插入操作的具体实现细节可能与这里描述的不一样。
比如,向一个已经满了的叶结点插入一个数据项时,该叶结点分裂成两个结点,并将中间数据项上移到该结点的双亲结点。
3)删除操作
删除操作可能会导致结点合并。具体描述参考算法导论。
比如,还可以这样来处理:当某个节点不包含的数据项已经达到最小时,可以从邻节点 “领养” 一个数据项。当邻节点也不足时,则将这两个节点合并成一个节点。
三,B树与B+树的主要区别
最主要的区别就是:B树中非叶子结点可以存储数据,而B+树非叶子结点只存储索引,所有的数据都放在叶子结点上存储,且所有的叶子结点到根的距离是一样的(叶子结点都在同一层)。
参考:B树学习总结
https://www.tutorialcup.com/dbms/b-tree.htm
B-树(B+树) 学习总结的更多相关文章
- 字典树 trie树 学习
一字典树 字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种 二.性质 根节点不包含字符,除根节点以外的每一个节点都只包含一个字符: 从根节点到某一节点,路径上经过的字符串连接起 ...
- AlphaGo原理-蒙特卡罗树搜索+深度学习
蒙特卡罗树搜索+深度学习 -- AlphaGo原版论文阅读笔记 目录(?)[+] 原版论文是<Mastering the game of Go with deep neural ne ...
- 珂朵莉树(Chtholly Tree)学习笔记
珂朵莉树(Chtholly Tree)学习笔记 珂朵莉树原理 其原理在于运用一颗树(set,treap,splay......)其中要求所有元素有序,并且支持基本的操作(删除,添加,查找......) ...
- 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))
函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...
- 树链剖分学习&BZOJ1036
题目传送门 树链剖分,计算机术语,指一种对树进行划分的算法,它先通过轻重边剖分将树分为多条链,保证每个点属于且只属于一条链,然后再通过数据结构(树状数组.SBT.SPLAY.线段树等)来维护每一条链. ...
- 外排序 & 败者树 & 多路归并-学习
来来来,根据这篇文章,学一下败者树吧: http://blog.csdn.net/whz_zb/article/details/7425152 一.胜者树 胜者树的一个优点是,如果一个选手的值改变了, ...
- 浅谈树套树(线段树套平衡树)&学习笔记
0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...
- 数据结构和算法学习笔记十五:多路查找树(B树)
一.概念 1.多路查找树(multi-way search tree):所谓多路,即是指每个节点中存储的数据可以是多个,每个节点的子节点数也可以多于两个.使用多路查找树的意义在于有效降低树的深度,从而 ...
- *衡树 Treap(树堆) 学习笔记
调了好几个月的 Treap 今天终于调通了,特意写篇博客来纪念一下. 0. Treap 的含义及用途 在算法竞赛中很多题目要使用二叉搜索树维护信息.然而毒瘤数据可能让二叉搜索树退化成链,这时就需要让二 ...
- 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 & 3236 [Ahoi2013] 作业 题解
[原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 978 Solved: 476 Descri ...
随机推荐
- WebService技术,服务端and客户端JDK-wsimport工具(一)
使用webservice服务,需要了解几个名词:soap 简单对象协议.http+xml . WSDL 先看下代码结构: 服务端代码与客户端代码分别处于两不同的包中 一.服务端内容 服务端: @Web ...
- 使用node-webkit(v0.35.5)和innosetup(3.6.1)打包将web程序打包为桌面客户端(安装包)
这边主要是有一个客户,需要在电视机上安装一个客户端,含有视频直播功能:刚开始我们采用的webapp打包成apk安装在电视机上,发现摄像头监控画面根本无法播放(apk在手机上可以正常播放视频):排除一些 ...
- Houdini Linux Crack
安装 破解停止服务 /etc/init.d/sesinetd stop 刪除sesinetd | 拷贝破解文件sesinetd | 修改sesinetd的权限(读写权限) cd /usr/lib/se ...
- python 游戏(猜数字)
1. 构造猜数字核心函数 import random def guess_core(guess_min,guess_max,guess_counrt): '''猜数字核心判断函数 :param gue ...
- unity上传app store遇到的一些问题
记录ios发布时遇到的一些问题 注:如果你是用mac开发,那就在Unity里直接BuildAndRun就直接可以导到XCode里,如果是win,那就先打包成ios包,在传导Xcode里打开,不过可能会 ...
- 华为笔试——C++字符串四则运算的实现
题目:字符串四则运算的实现 有字符串表示的一个四则运算表达式,要求计算出该表达式的正确数值.四则运算即:加减乘除"+-*/",另外该表达式中的数字只能是1位(数值范围0~9),运算 ...
- 2013337朱荟潼 Linux第五章读书笔记——系统调用
摘要: [20135337朱荟潼]原创作品转载请注明出处 第五章 系统调用 5.1 与内核通信 中间层 作用三个:1.为用户空间提供一种硬件的抽象接口:2.保证系统稳定和安全:3.除异常和陷入,是内核 ...
- 评审other's意见
评审意见 1.组 a.界面不友好 b.没连数据库 2.组 a.没连数据库 b.无智能匹配当前时间 3.组 a.基本功能实现 b.界面未优化 4.组 ourselves 5.组 a.各反面较为完善 6. ...
- 11慕课网《进击Node.js基础(一)》Buffer和Stream
Buffer 用来保存原始数据 (logo.png) 以下代码读取logo.png为buffer类型 然后将buffer转化为string,新建png 可以将字符串配置: data:image/png ...
- request.getParameter中文乱码问题解决办法
new String(request.getParameter("pageNo").getBytes("ISO-8859-1"),"UTF-8&quo ...