定义:
B树是一种平衡多路查找树,满足以下条件:
核心性质:
易错点:
算法步骤:
实现代码(伪代码):
void BTreeInsert(BTree *T, KeyType k) {
if (T == NULL) return;
if (T->keynum < m-1) { // 直接插入
InsertKey(T, k);
} else { // 分裂
BTreeNode *newNode = SplitNode(T);
KeyType midKey = T->keys[⌈m/2⌉];
InsertKey(parent, midKey); // 中间关键字插入父结点
// 递归处理父结点
}
}
难点:
算法步骤:
实现代码(伪代码):
void BTreeDelete(BTree *T, KeyType k) {
Node *target = SearchNode(T, k);
if (target == NULL) return;
if (target->isLeaf) {
DeleteFromLeaf(target, k);
} else { // 非叶结点处理
KeyType predecessor = FindPredecessor(target, k);
ReplaceKey(target, k, predecessor);
target = predecessorNode; // 转换为叶结点删除
}
// 调整平衡
while (target->keynum < ⌈m/2⌉-1) {
if (canBorrowFromSibling(target)) {
BorrowFromSibling(target);
} else {
MergeWithSibling(target);
target = parent; // 向上递归调整
}
}
}
易错点:
题目(2022年408):
在5阶B树中插入关键字序列{15, 22, 3, 8, 71, 50},画出最终形态。
解析:
题目:给定4阶B树初始状态如下,删除关键字30后的结构如何调整?
[20, 40]
/ | \
[10,15] [25,30] [45,50]
答案:
定义:
B+树是B树的变体,满足:
核心性质:
与B树差异:
特性 | B树 | B+树 |
---|---|---|
关键字存储 | 非叶结点存实际数据 | 非叶结点仅存索引 |
叶结点链接 | 无 | 叶结点通过指针链接 |
查找终止位置 | 可能在非叶结点 | 必须到达叶结点 |
易错点:
算法步骤:
代码实现要点:
void BPlusTreeInsert(BPlusTree *T, KeyType k) {
LeafNode *leaf = FindLeaf(T, k);
InsertIntoLeaf(leaf, k);
if (leaf->keynum > m-1) {
LeafNode *newLeaf = SplitLeaf(leaf);
InsertIntoParent(leaf, newLeaf->keys[0], newLeaf);
}
}
难点:
算法步骤:
实现细节:
void BPlusTreeDelete(BPlusTree *T, KeyType k) {
LeafNode *leaf = FindLeaf(T, k);
DeleteFromLeaf(leaf, k);
if (leaf->keynum < ⌈m/2⌉) {
if (canBorrowFromSibling(leaf)) {
BorrowFromSibling(leaf);
} else {
MergeWithSibling(leaf);
// 递归调整父结点关键字
}
}
}
易错点:
题目(2023年408):
下列关于B+树的描述中,错误的是:
A. 叶结点包含全部关键字
B. 非叶结点关键字是子树的最大值
C. 支持高效的范围查询
D. 非叶结点存储实际数据记录
答案:D
解析:B+树的非叶结点仅存储索引,实际数据存储在叶结点
题目:在3阶B+树中插入序列{5, 8, 3, 7, 1},画出最终结构。
答案:
非叶结点: [5,7]
叶结点链表: [1,3] ↔ [5,7] ↔ [8]
公式推导:
真题应用(2018年408):
已知某5阶B树含24个关键字,求最小高度。
解法:
h m i n = log 5 ( 24 + 1 ) = 2 h_{min} = \log_5 (24+1) = 2 hmin=log5(24+1)=2
题目:给定4阶B树初始结构如下,依次删除35、40,画出每步结果:
[30, 40]
/ | \
[10,20] [35] [45,50]
解析:
BTreeNode* BTreeSearch(BTreeNode *root, KeyType k) {
int i = 0;
while (i < root->n && k > root->keys[i]) i++;
if (i < root->n && k == root->keys[i]) return root;
if (root->isLeaf) return NULL;
return BTreeSearch(root->children[i], k);
}
void BPlusTreeRangeQuery(BPlusTree *T, KeyType low, KeyType high) {
LeafNode *start = FindLeaf(T, low);
while (start != NULL && start->keys[0] <= high) {
for (int i=0; i<start->n; i++) {
if (start->keys[i] >= low && start->keys[i] <= high) {
printf("%d ", start->keys[i]);
}
}
start = start->next;
}
}
对比项 | B树 | B+树 |
---|---|---|
数据存储 | 非叶结点存数据 | 仅叶结点存数据 |
查询终止 | 可能在非叶结点找到数据 | 必须到达叶结点 |
范围查询 | 效率低 | 通过叶结点链表高效支持 |
分裂方式 | 中间关键字上移 | 叶结点分裂时复制关键字到父结点 |
注:建议结合《数据结构(C语言版)》与王道考研教材进行系统复习。