好的,我要试试这个,也许 SO 的其他好人可以提供帮助。您知道如何将红色节点视为指标的一种方式
- 树中有不平衡/新节点的地方,以及
- 有多少不平衡。
这就是为什么所有新节点都是红色的。当节点(局部)平衡时,它们会发生颜色翻转,红色传递给父节点,现在父节点相对于其兄弟节点可能看起来不平衡。
例如,考虑一种情况,您将节点从大到小添加。你从节点 Z 开始,它现在是根节点并且是黑色的。您添加节点 Y,它是红色的,是 Z 的左子节点。您添加一个红色 X 作为 Z 的子节点,但现在您有两个连续的红色,因此您向右旋转,重新着色,并且您有一个平衡的全黑(没有不平衡/“新节点”!)植根于 Y [第一幅图] 的树。现在按顺序添加 W 和 V。起初它们都是红色[第二张图],但立即将 V/X/W 向右旋转,颜色翻转,因此只有 X 是红色的[第三张图]。这很重要:X 为红色表示 Y 的左子树有 2 个节点不平衡,或者换句话说,左子树中有两个新节点。所以红色链接的高度是新的、可能不平衡的节点的数量:
请注意,在添加节点时,红色总是向上传递:在颜色翻转中,两个红色子节点变为黑色(=局部平衡),同时将其父节点着色为红色。本质上,删除的作用是反转这个过程。就像一个新节点是红色的一样,我们也总是想删除一个红色节点。如果节点不是红色的,那么我们想先把它变成红色。这可以通过颜色翻转来完成(顺便说一下,这就是为什么第 3 页代码中的颜色翻转实际上是颜色中性的)。所以如果我们要删除的孩子是黑色的,我们可以通过颜色翻转它的父母让它变成红色。现在保证孩子红了。
下一个要处理的问题是,当我们开始删除时,我们不知道要删除的目标节点是否为红色。一种策略是先找出答案。但是,根据我对您的第一个参考资料的阅读,那里选择的策略是确保删除的节点可以变为红色,方法是在我们向下搜索树时将红色节点“推”到搜索节点前面要删除的节点。这可能会创建不必要的红色节点,fixUp()
程序将在备份树的过程中解决这些节点。fixUp()
大概保持通常的 LLRBT 不变量:“没有连续的红色节点”和“没有正确的红色节点”。
不确定这是否有帮助,或者我们是否需要对代码进行更详细的检查。