B树和B+树

2-3树

一颗2-3树或为一颗空树,或有以下节点组成:

2-节点,含有一个元素和两个子树(左右子树),左子树所有元素的值均小于它父节点,右子树所有元素的值均大于它父节点;

3-节点,还有两个元素和三个子树(左中右子树),左子树所有元素的值均小于它父节点,中子树所有元素的值都位于父节点两个元素之间,右子树所有元素的值均大于它父节点;

子树也是空树、2-节点或者3-节点;

没有元素相等的节点。

B树

B 树可以看作是对2-3查找树的一种扩展,即他允许每个节点有M-1个子节点。

  • 根节点至少有两个子节点
  • 每个节点有M-1个key,并且以升序排列
  • 位于M-1和M key的子节点的值位于M-1 和M key对应的Value之间
  • 其它节点至少有M/2个子节点

B+树

B+树是对B树的一种变形树,它与B树的差异在于:

  • 有k个子结点的结点必然有k个关键码;
  • 非叶结点仅具有索引作用,跟记录有关的信息均存放在叶结点中。
  • 树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录

B+ 树的优点在于:

  • 由于B+树在内部节点上不好含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子几点上关联的数据也具有更好的缓存命中率。
  • B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

https://www.cnblogs.com/makai/p/10861296.html

### B与B+的区别 BB+都是多路平衡查找,适用于外部存储大规模数据索引,但它们在结构功能上存在显著差异。 #### 1. **关键字与节点关系** B中,每个节点既可以存储关键字,也可以存储数据。对于一个m阶的B来说,每个节点最多包含m-1个关键字,同时子节点数量也最多为m。而B+的每个节点可以包含m个关键字,并且所有数据都存储在叶子节点中。非叶子节点仅存储索引信息,这使得B+更适用于大数据量的索引结构。 #### 2. **数据存储位置** B的数据可以存储在任意节点中,包括根节点、中间节点叶子节点。而B+的数据仅存储在叶子节点中,中间节点仅用于索引。这种设计使得B+能够更高效地进行批量数据访问。 #### 3. **分支节点的构造** B的分支节点存储关键字子节点指针,同时可能存储数据。而B+的分支节点仅存储关键字子节点指针,不存储实际数据。这意味着在相同的页大小(例如16KB)下,B+可以存储更多的索引信息,从而减少的高度,提高查询效率。 #### 4. **查询性能** B在查询时,可能在非叶子节点就找到所需数据,因此查询路径较短。但B+的查询路径固定,从根节点到叶子节点的高度一致,因此查询性能更加稳定。这种稳定性对于数据库索引尤为重要。 #### 5. **区间访问** B+的叶子节点通过链表连接,支持高效的区间查询。例如,数据库中的范围查询(如`SELECT * FROM table WHERE id BETWEEN 100 AND 200`)可以利用B+的这一特性快速完成。而B的叶子节点之间没有链接,区间查询效率较低。 #### 6. **磁盘I/O效率** 由于B+的非叶子节点不存储数据,每个节点可以容纳更多的关键字,从而减少的高度。这使得B+在磁盘I/O操作上更加高效,尤其适合需要频繁读取外部存储的场景。 ### B与B+的应用场景 #### B的应用场景 B适用于需要频繁更新查询的小规模数据集。由于B的非叶子节点存储数据,它在某些特定的场景中具有优势,例如: - **内存数据库**:当数据量较小且需要快速访问时,B可以减少磁盘I/O操作。 - **嵌入式系统**:在资源受限的环境中,B的简单结构可以提供较高的性能[^3]。 #### B+的应用场景 B+由于其结构特性,广泛应用于大规模数据存储索引系统,主要包括: - **数据库索引**:如MySQL的InnoDB引擎使用B+作为主键索引的底层实现,支持高效的查询范围扫描。 - **文件系统**:B+的叶子节点链表结构支持高效的文件顺序访问,例如在Linux文件系统中。 - **分布式存储系统**:B+的稳定查询性能高效的区间访问能力使其成为分布式数据库存储系统的首选索引结构[^2]。 ### 示例代码:B+的插入操作 以下是一个简化的B+插入操作的Python实现,用于展示B+的基本结构插入逻辑: ```python class BPlusTreeNode: def __init__(self, order, is_leaf): self.order = order self.is_leaf = is_leaf self.keys = [] self.children = [] def insert(self, key): if self.is_leaf: self.keys.append(key) self.keys.sort() else: child = self.get_child_for_key(key) child.insert(key) if len(child.keys) >= self.order: self.split_child(child) def split_child(self, child): new_node = BPlusTreeNode(child.order, child.is_leaf) mid = len(child.keys) // 2 new_node.keys = child.keys[mid:] child.keys = child.keys[:mid] if not child.is_leaf: new_node.children = child.children[mid:] child.children = child.children[:mid] self.keys.append(new_node.keys[0]) self.keys.sort() index = self.children.index(child) self.children.insert(index + 1, new_node) def get_child_for_key(self, key): for i, k in enumerate(self.keys): if key < k: return self.children[i] return self.children[-1] class BPlusTree: def __init__(self, order): self.order = order self.root = BPlusTreeNode(order, is_leaf=True) def insert(self, key): self.root.insert(key) if len(self.root.keys) >= self.order: new_root = BPlusTreeNode(self.order, is_leaf=False) new_root.keys = [self.root.keys[0]] new_root.children = [self.root] self.root = new_root # 示例:创建一个B+并插入几个键 tree = BPlusTree(order=4) for key in [10, 20, 5, 6, 15, 30]: tree.insert(key) ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值