红黑树双红冲突修复包含五类操作:一、变色处理;二、右倾结构左旋;三、左倾结构右旋;四、之字形结构先右后左双旋;五、color字段原子性维护。

一、双红冲突检测与变色处理
当新插入节点为红色且其父节点也为红色时,违反红黑树性质4(任意路径上不能有两个连续的红色节点),此时触发双红冲突。变色操作是修复的第一优先级手段,无需改变树结构,仅通过调整节点颜色即可恢复局部平衡。
1、判断当前节点z是否为根节点,若是,则直接将z.color设为黑色,结束修复流程。
2、获取z的父节点p和祖父节点g,确认p.color == RED且g.color == BLACK。
3、获取z的叔节点u(p的兄弟节点),若u存在且u.color == RED,则执行三节点同变色:将p.color设为BLACK,u.color设为BLACK,g.color设为RED。
4、将z更新为g,继续向上检测祖父节点是否引发新的双红冲突。
二、左旋操作在右倾双红结构中的应用
当双红冲突发生在“父节点为祖父右子、当前节点为父节点右子”的右倾链上,且叔节点为黑色或空时,需通过左旋将结构转化为可统一处理的左倾形态,再配合变色完成修复。
1、确认p == g->right且z == p->right,且u == nullptr 或 u.color == BLACK。
2、以g为旋转轴执行左旋:令p成为g的新父节点,g变为p的左子节点,原p->left子树(若存在)挂接至g->right。
3、交换p与g的颜色:p.color = BLACK; g.color = RED;
4、此时双红冲突转移至p与g之间,但结构已转为“父为左子、当前为左子”形态,交由第三种情形处理。
三、右旋操作在左倾双红结构中的应用
当双红冲突发生在“父节点为祖父左子、当前节点为父节点左子”的左倾链上,且叔节点为黑色或空时,直接对祖父节点执行右旋,并调整颜色,可一次性消除冲突并满足红黑树全部性质。
1、确认p == g->left且z == p->left,且u == nullptr 或 u.color == BLACK。
2、以g为旋转轴执行右旋:令p成为g的新父节点,g变为p->right,原p->right子树(若存在)挂接至g->left。
3、执行关键颜色重赋值:p.color = BLACK; g.color = RED;
4、该操作后,从z到根的每条路径黑色节点数保持不变,且无连续红节点,修复完成。
四、左右双旋处理之字形双红结构
当双红冲突呈“父为祖父左子、当前为父节点右子”或“父为祖父右子、当前为父节点左子”的之字形排列,且叔节点为黑色或空时,需先局部旋转将其转化为直线结构,再执行对应单旋与变色。
1、若p == g->left且z == p->right,则先以p为轴对z执行右旋,使z上升为p位置,z->right子树移至p->left。
2、右旋后更新指针关系:令z原父节点p变为z->left,z取代p成为g->left。
3、再以g为轴对z执行左旋,使z成为新子树根,g降为其左子,原z->left(即p)挂接至g->right。
4、执行最终颜色设定:z.color = BLACK; g.color = RED;
五、节点结构体中颜色字段的原子性维护
红黑树修复逻辑高度依赖color字段的准确状态,必须确保所有路径对color的读写具有可见性与一致性,尤其在多线程模拟或调试场景下避免因编译器优化导致颜色未及时刷新。
1、定义color字段为enum class Color { RED, BLACK }; 并使用private访问控制。
2、所有对外暴露的color访问均通过const Color& get_color() const noexcept成员函数返回引用,禁止直接暴露color成员变量。
3、所有变色操作必须调用void set_color(Color c) noexcept,内部添加std::atomic_thread_fence(std::memory_order_release)以防止指令重排。
4、在旋转函数入口处插入std::atomic_thread_fence(std::memory_order_acquire),确保旋转前所有color变更已对当前线程可见。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











