红黑树的删除操作
红黑树是一种自平衡的二叉搜索树,它通过特定的规则和旋转操作来维护平衡,确保最坏情况下的操作时间复杂度为O(log n)。删除操作是红黑树中最复杂的部分,因为它可能破坏红黑树的平衡性质,需要通过一系列调整来恢复平衡。
红黑树的性质
在讲解删除前,先回顾红黑树的五个性质:
- 每个节点是红色或黑色。
- 根节点是黑色。
- 每个叶子节点(NIL节点)是黑色。
- 红色节点的子节点必须是黑色(即不能有两个连续的红色节点)。
- 从任一节点到其每个叶子节点的所有路径都包含相同数量的黑色节点(黑色高度相同)。
删除操作的基本步骤
删除操作分为两步:
- 执行标准二叉搜索树(BST)的删除:找到待删除节点,并根据其子节点数量处理。
- 平衡调整:如果删除的节点是黑色,可能违反性质5,需要通过旋转和重新着色来恢复平衡。
步骤1:BST删除
设待删除节点为z,分三种情况:
- 情况A:
z没有子节点(或只有NIL叶子节点)。直接删除z,并将其父节点指向NIL。 - 情况B:
z有一个子节点。用子节点替换z,并删除z。 - 情况C:
z有两个子节点。找到z的后继节点y(右子树中的最小节点),将y的值复制到z,然后删除y(此时y最多有一个子节点,转化为情况A或B)。
注意:实际删除的节点可能是z或其后继y。记实际被删除的节点为d(其子节点最多一个),替换d的子节点为c(可能为NIL)。如果d是黑色,删除后需要调整。
步骤2:平衡调整
如果被删除的节点d是红色,直接删除不会破坏性质5(黑色高度不变)。但如果d是黑色,则经过d的路径黑色节点减少1,违反性质5。调整过程以c(替换d的节点)为中心,通过迭代处理以下情况(假设c是左孩子,右孩子情况对称):
-
情况1:
c是红色。
将c染黑即可(补偿丢失的黑色节点)。调整结束。 -
情况2:
c是黑色,且其兄弟节点s是红色。
此时父节点p必须是黑色(因s红)。通过左旋(若c是左孩子)或右旋(若c是右孩子)使p和s交换颜色:p染红,s染黑。旋转后,c的新兄弟是原兄弟的子节点(黑色),转化为情况3、4或5。 -
情况3:
c是黑色,兄弟s是黑色,且s的两个子节点都是黑色。
将s染红,此时通过p的路径黑色高度统一减少1,但p可能为红或黑。若p原为红色,将p染黑即可补偿;若p原为黑色,则以p为新c,递归向上调整。 -
情况4:
c是黑色,兄弟s是黑色,s的近侄子(与c同侧的侄子)是红色,远侄子黑色。
通过旋转使近侄子成为新兄弟:例如c是左孩子时,右旋s并交换s和近侄子颜色(s染红,近侄子染黑)。转化为情况5。 -
情况5:
c是黑色,兄弟s是黑色,远侄子红色。
通过旋转父节点p:例如c是左孩子时,左旋p,并交换p和s的颜色,将远侄子染黑。此时黑色高度恢复,调整结束。
示例说明
假设删除节点d(黑色)后,其子节点c(黑色)替换位置,且c的兄弟s为红色(情况2)。
- 左旋父节点
p,p染红,s染黑。此时c的新兄弟是s的左孩子(黑色)。 - 若新兄弟的子节点全黑(情况3),将新兄弟染红,
p成新焦点。若p原为红,染黑结束;否则递归向上。 - 若遇到情况4或5,通过旋转直接恢复平衡。
关键点
- 调整过程最多遍历O(log n)次树高。
- 旋转操作(左旋/右旋)保持BST性质,重新着色修复红黑性质。
- 情况3可能引发递归,但每次递归向上移动,最终在根节点或红色节点终止。
通过以上步骤,红黑树在删除后仍能维持平衡,确保高效操作。