B树的理解
在大型数据存储过程中,由于计算机内存的大小毕竟有限,更多的时候,我们会把数据存放在硬盘上,这时对于数据查找的耗时,更多是出现在磁盘的读取上。以一台普通计算机为例(500-MIPS)1S可以执行5E条指令,而一个7200转的硬盘,一秒钟大约可以执行120次的磁盘读取。
对于AVL树的结构,我们已经把查找的时间复杂度降到了logN,如果放到了硬盘读取上,降低后的耗时仍然无法满足我们的需求。
举个例子:如果计算机有20个用户,那么单个用户1S可以执行约2500万次指令和6次硬盘读取,如果数据的量是1000万,log1000000≈24,一次成功的查找是1.38 × 24 ≈ 32次磁盘访问,也就是5S的时间。很显然这是无法忍受的。
要解决上述问题,二叉树已经无法满足,这时,我们可以通过增加树的分支,来让树结构拥有更少的高度。
B树(这里指B+树)的特性
1.数据项全存储在树叶节点上
2.非树叶节点拥有M-1个关键字,用来划分M个分支
3.树的节点的儿子数在2和M之间
4.除根外,所有非树叶节点的儿子数在M/2和M之间
5.所有的树叶都在相同的深度上并有L/2和L之间的数据项
上述特性中的M和L的拟定,用一个例子来说明方法:
每个节点代表的是一块磁盘区域,假设已知一块磁盘区域最多能容纳8192字节,现在又1000万的数据,每一个关键字是32个字节,每一个记录是256个字节。
那么非树叶节点存储的M-1个关键字和M个分支,一个分支是4个字节的话,需要的空间是32(M-1)和4M,总数是36M-32 不能超过8192,那么M的值最大是228。由于每个记录是256,最多可以把32个记录放入一个区块中,于是我们选择L=32。
一般在存储中,我们将根节点和下一层存于内存中,第三层之后存于磁盘中,这样就可以最大范围的利用内存和磁盘的优势了。
插入和删除
插入操作是,根据关键字找到插入数据所属的树叶节点,如果没有满,那么很简单,直接插入。如果已经达到了L的限度,那么需要对树叶进行分裂操作,让分裂的两个树叶都有L/2的数据量。同理,如果分裂后导致根节点也达到了L的限度,那么需要对根节点做同样的分裂操作。直到根节点也执行该操作,那么根节点转为儿子节点,在上一层增加新的根节点。这是唯一增加树高度的方式。
删除操作是插入的逆操作,如果达到了L/2的限度,需要进行合并操作。同样如果追溯到了根节点,可能会导致树的高度减少。