← 返回题目列表

B 树是如何删除节点的?为什么会「借位」和「合并」?

困难 第 21 / 25 题 更新于 2026/07/28
B树删除合并借位

简化版

删除后,如果节点关键字数低于下限(⌈m/2⌉-1),就「下溢」了,要修复。修复有两招:向兄弟「借位」——如果相邻兄弟节点关键字有富余(多于下限),就借一个过来(通过父节点「旋转」);「合并」——如果兄弟也不富余,就把当前节点、父节点的一个关键字、兄弟节点三者合并成一个节点。合并会让父节点少一个关键字,可能连锁向上,甚至让树变矮一层。

详细版

删除的第一步是把「删非叶子节点的关键字」转化为「删叶子节点的关键字」:

  • 若删的关键字在内部节点,用它的前驱或后继(左子树最大 / 右子树最小,都在叶子)替换它,转为删那个叶子里的关键字——和 BST 删除思路一致。

删完后若节点关键字数 ≥ ⌈m/2⌉-1(满足下限),结束。若下溢(少于下限),修复:

修复手段触发条件做法
借位(旋转)相邻兄弟关键字 > 下限(有富余)父节点的分隔关键字下移到当前节点,兄弟的一个关键字上移到父节点
合并相邻兄弟关键字 = 下限(借不动)当前节点 + 父节点分隔关键字 + 兄弟,三者合并成一个节点

合并后父节点少一个关键字,若父节点因此下溢,向上递归同样的借位/合并;若根被合并到只剩一个孩子,树高 -1

完整版教学

一、删除为什么比插入复杂

插入只会「撑破」节点(溢出),修复手段单一——分裂。删除会让节点「变瘪」(下溢,低于半满下限),而修复要看邻居的脸色:邻居富余就「借」,邻居也紧张就「合并」。两种情况、还可能连锁向上,所以删除是 B 树里最繁琐的操作,和红黑树删除一样属于「情况多」的难点。

二、先化简:把删除转移到叶子

和 BST 删除同理,删一个内部节点的关键字会留下一个「洞」,不好处理。所以先用前驱(该关键字左子树里最大的,在叶子)或后继(右子树里最小的,在叶子)的值替换它,再转为删除那个叶子里的关键字。这样所有真正的删除都发生在叶子层,只需处理叶子的下溢。

三、借位:向富余的兄弟借一个(旋转)

如果被删节点下溢了,但它相邻的兄弟节点关键字有富余(多于下限),就可以「借」——但不是直接搬,而是通过父节点旋转

借位(当前节点下溢,右兄弟富余):
- 父节点里「分隔当前节点与兄弟」的那个关键字,下移到当前节点(补上缺口)
- 兄弟节点最靠近的那个关键字,上移到父节点,填补父节点的空缺

相当于「兄弟 → 父 → 当前节点」转一圈,把兄弟多的一个匀给当前节点,同时保持所有节点有序、父节点分隔关系正确。借位是局部操作,不会连锁向上。

四、合并:兄弟也不富余时

如果相邻兄弟也只有下限那么多关键字(借了它自己就下溢),就不能借,只能合并:把「当前节点 + 父节点里的分隔关键字 + 兄弟节点」三者拼成一个节点

合并(当前节点和右兄弟都恰好下限):
[当前节点的关键字] + [父的分隔关键字] + [兄弟的关键字]  → 合成一个节点
父节点因此少了一个关键字(分隔关键字被拿走了)

合并把两个「半满」的节点并成一个(正好不超上限),代价是父节点少了一个关键字

五、合并为什么会连锁、让树变矮

合并从父节点「抽走」了一个分隔关键字,如果父节点因此下溢,就要对父节点再做借位/合并……这种连锁可能一路传到根。如果根节点的关键字被合并到只剩 0 个(只剩一个孩子),就把这个唯一的孩子作为新根,整棵树变矮一层。这是 B 树唯一变矮的方式——和插入时「根分裂让树长高」正好对称。全程所有叶子始终同层,平衡得以维持。

六、常见误区与追问

考点正确口径
借位兄弟节点关键字超过下限时,通过父节点旋转补足
合并兄弟也到下限时,与父关键字合并
连锁父节点减少后可能继续向上修复
before descending:
  ensure child has enough keys
if sibling rich: borrow
else: merge child + separator + sibling

B 树删除的核心目标是:删除后每个非根节点仍至少半满。

  • 误区:B 树删除只要把 key 从节点里移除。 移除后可能低于最小关键字数,必须借位或合并恢复性质。
  • 误区:内部节点删除不能转成叶子删除。 常见做法用前驱或后继替换内部 key,再到叶子层删除替代 key。
  • 误区:借位只是兄弟直接给一个 key。 借位要经过父节点分隔 key 旋转,才能保持节点内有序和子树范围正确。
  • 追问:什么时候合并? 目标孩子和相邻兄弟都只有最少关键字,无法借位时合并并拉下父分隔 key。
  • 追问:为什么删除可能让树变矮? 根节点被合并到只剩 0 个 key 时,唯一孩子上升为新根,树高减少一层。
  • 追问:复杂度是多少? 删除沿树高下降并可能向上调整,层数 O(log_m n),磁盘 IO 也按树高估算。

七、加强记忆

B 树删除:先把删内部节点转化为用前驱/后继替换再删叶子。删完若节点下溢(< ⌈m/2⌉-1)就修复:兄弟富余→借位(父的分隔键下移、兄弟的键上移,转一圈)兄弟也紧张→合并(当前+父分隔键+兄弟 合成一个节点)。合并使父节点少一个键,可能连锁向上,若根被合并到只剩一个孩子则树高 -1(唯一变矮方式,与插入长高对称)。