B树、B+树

B树是一种降低磁盘I/O操作数的数据结构,常用于数据库系统。B树的每个节点可包含多个关键字,且每个内部节点至少有t-1个关键字,最多有2t个孩子。B树的高度直接影响其操作效率,搜索、插入和删除操作的时间复杂度为O(log_t n)。B+树是B树的变种,适用于范围查询和全序遍历。

B树、B+树


一、B树

B树类似于红黑树,但它在降低磁盘I/O操作数方面要更好一些。许多数据库操作系统使用B树或者B树的变种来存储信息。

B树与红黑树不同之处在于B树的结点可以有很多孩子。所以,可以使用B树在时间O(lgn)内完成一些动态集合的操作。

若B树的一个内部结点x包含x.n个关键字,那么结点x就有x.n+1个孩子。结点x中的关键字就是分隔点。

这里写图片描述

1. B树的定义

一棵B树T是具有以下性质的有根树(根为T.root):

  • 每个结点x有下面属性:
    • x.n,当前存储在结点x中的关键字个数;
    • x.n个关键字本身x.key1,x.key2,,x.keyx.n,以非降序存放,使得x.key1x.key2x.keyx.n;
    • x.leaf,一个布尔值,如果x是叶结点,则为TRUE;如果x为内部结点,则为FALSE。
  • 每个内部结点x还包括x.n+1个指向其孩子的指针x.c1x.
### B与B+的概念 B是一种自平衡的多路查找,其设计目的是为了减少磁盘I/O操作次数。它通过确保所有叶子节点处于同一层来维持平衡性[^1]。B+是B的一种变体,保留了B的基本特性,同时在结构上进行了改进以优化范围查询顺序访问性能[^3]。 ### B与B+的区别 1. **节点存储结构** 在B中,每个节点既可以存储数据(键值对),也可以作为索引使用。而在B+中,内部节点仅存储索引信息,所有数据记录都存储在叶子节点中[^2]。 2. **叶子节点链表** B+的所有叶子节点通过指针链接形成一个有序链表,这使得范围查询顺序扫描更加高效。而B不具备这样的特性,导致其在范围查询时效率较低[^3]。 3. **数据分布** B的数据分布在所有节点中,包括非叶子节点。而B+的数据只集中在叶子节点上,这种设计减少了重复存储的可能性,并提高了空间利用率[^1]。 4. **查询效率** 对于单点查询,BB+的表现差异不大。然而,在范围查询场景下,B+由于其叶子节点链表的设计,能够显著提升性能[^2]。 5. **插入与删除操作** B+插入删除时,由于数据集中存储在叶子节点上,调整操作相对简单,可以避免频繁地调整非叶子节点中的数据。 ### 实现细节 以下是一个简单的B+实现示例,展示了如何构建查询: ```python class BPlusTreeNode: def __init__(self, is_leaf=False): self.keys = [] self.children = [] self.is_leaf = is_leaf self.next_leaf = None # 指向下一个叶子节点 class BPlusTree: def __init__(self, t): self.root = BPlusTreeNode(True) self.t = t def insert(self, key): root = self.root if len(root.keys) == (2 * self.t) - 1: new_node = BPlusTreeNode() self.root = new_node new_node.children.append(root) self.split_child(new_node, 0) self.insert_non_full(new_node, key) else: self.insert_non_full(root, key) def split_child(self, node, index): t = self.t child = node.children[index] new_node = BPlusTreeNode(child.is_leaf) node.children.insert(index + 1, new_node) node.keys.insert(index, child.keys[t - 1]) new_node.keys = child.keys[t:(2 * t) - 1] child.keys = child.keys[0:t - 1] if not child.is_leaf: new_node.children = child.children[t:(2 * t)] child.children = child.children[0:t] def insert_non_full(self, node, key): i = len(node.keys) - 1 if node.is_leaf: node.keys.append(None) while i >= 0 and key < node.keys[i]: node.keys[i + 1] = node.keys[i] i -= 1 node.keys[i + 1] = key else: while i >= 0 and key < node.keys[i]: i -= 1 i += 1 if len(node.children[i].keys) == (2 * self.t) - 1: self.split_child(node, i) if key > node.keys[i]: i += 1 self.insert_non_full(node.children[i], key) ``` ### 应用场景 - **B的应用场景** B适用于需要频繁进行随机访问的场景,例如文件系统中的元数据管理、数据库的索引结构等。由于其支持快速的单点查询,因此在某些特定场景下仍然具有优势[^1]。 - **B+的应用场景** B+广泛应用于数据库系统(如MySQL的InnoDB引擎)文件系统中。它的优点在于能够高效处理范围查询顺序访问,因此非常适合大规模数据集的索引构建[^2]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值