#pragma once #include #include "TreeNode.h" template class RBTree { private: TreeNode* root; TreeNode* nul; int size; void initNul() { nul = new TreeNode(0, nul, nul, nul); nul->color = Color::RED; } void inorder(TreeNode* x); void dispose(TreeNode* x) { if (x == nullptr || x == nul) return; dispose(x->left); dispose(x->right); delete x; //重点不能delete nul(作为全局的哨兵) } public: RBTree() : size(0) { initNul(); root = nul; } RBTree(TreeNode* r, int s) : root(r), size(s) { initNul(); } ~RBTree() { dispose(root); root = nullptr; delete nul; //删除哨兵,需要删除 } TreeNode* RotateLeft(TreeNode* x);//RR TreeNode* RotateRight(TreeNode* x);//LL void insert(const T& e); void fixinsert(TreeNode* x); void fixdelete(TreeNode* x); void inorder() { inorder(root); } void erase(const T& e); TreeNode* find(const T& e); }; template inline TreeNode* RBTree::RotateLeft(TreeNode* x) { TreeNode* y = x->right; // 右孩子 TreeNode* T2 = y->left; // y 的左子树暂存 // 左旋 y->left = x; x->right = T2; // 更新 parent 指针 if (T2) T2->parent = x; // 如果 T2 存在 y->parent = x->parent; // y 接上 x 的父节点 if (x->parent == nul) { // x 是根节点 root = y; } else if (x == x->parent->left) { x->parent->left = y; } else { x->parent->right = y; } x->parent = y; return y; // 返回新子树根 } template TreeNode* RBTree::RotateRight(TreeNode* x) { //有parent,不需要递归,直接修改parent TreeNode* y = x->left; TreeNode* T2 = y->right; // 旋转 y->right = x; x->left = T2; // 更新 parent 指针 if (T2) T2->parent = x; // 如果 T2 存在 y->parent = x->parent; // y 接上 x 的父节点 if (x->parent == nul) { // x 是根节点 root = y; } else if (x == x->parent->left) { x->parent->left = y; } else { x->parent->right = y; } x->parent = y; return y; // 返回新子树根 } template inline void RBTree::inorder(TreeNode* x) { if (x == nul) return; inorder(x->left); std::cout << x->element << " "; inorder(x->right); } template inline void RBTree::insert(const T& e) { TreeNode* p = new TreeNode(e, nul, nul, nul); TreeNode* current = root; TreeNode* parent = nul; //BST插入,有parent就不需要递归节点了 while (current != nul) { parent = current; if (e < parent->element) current = parent->left; else current = parent->right; } p->parent = parent; if (parent == nul) root = p; if (parent == nul) root = p; else if (e < parent->element) parent->left = p; else parent->right = p; //FixInsert fixinsert(p); } template inline void RBTree::fixinsert(TreeNode* x) { while (x != root && x->parent->color == Color::RED) { //看叔叔 if (x->parent->parent->left == x->parent) { //左节点 if (x->parent->parent->right->color == Color::RED) { //叔叔红 x->parent->color = x->parent->parent->right->color = Color::BLACK; x->parent->parent->color = Color::RED; //fixinsert(x->parent->parent);递归不好,容易重复判断,不易处理根节点颜色 x = x->parent->parent; continue; } if (x == x->parent->left) { //LL//先变色祖父,父亲 x->parent->parent->color = Color::RED; x->parent->color = Color::BLACK; //再右旋 RotateRight(x->parent->parent); } //LR if (x == x->parent->right) { //变成LL x = x->parent; RotateLeft(x); //不需要再LL了,下一个循环自动变成LL } } //else对称情况,父亲为右节点 else { //1-叔叔红 if (x->parent->parent->left->color == Color::RED) { x->parent->parent->left->color = Color::BLACK; x->parent->color = Color::BLACK; x->parent->parent->color = Color::RED; x = x->parent->parent; } //2-叔叔黑 else { //2-1-RL -> 调整为RR,再做下一步操作 if (x == x->parent->left) { x = x->parent; RotateRight(x); } //3-RR,接着上面的2-1 x->parent->color = Color::BLACK; x->parent->parent->color = Color::RED; RotateLeft(x->parent->parent); } } } root->color = Color::BLACK; } // x 表示被删除节点的替代节点(可能是 nul 哨兵) // 只有当被删节点或替代节点是黑色时,才需要进入 fixdelete template void RBTree::fixdelete(TreeNode* x) { while (x != root && x->color == Color::BLACK) { // 情况1:x 是左孩子 if (x == x->parent->left) { TreeNode* w = x->parent->right; // x 的兄弟节点 // case 1: 兄弟是红色 // -> 把兄弟染黑,父亲染红,然后左旋 // -> 转化为兄弟是黑色的情况 if (w->color == Color::RED) { w->color = Color::BLACK; x->parent->color = Color::RED; RotateLeft(x->parent); w = x->parent->right; // 更新兄弟 } // case 2: 兄弟是黑色,并且两个侄子(w->left, w->right)都是黑色 // -> 把兄弟染红,相当于把 "多余的黑色" 往上传递 // -> 修复过程继续向上进行 if (w->left->color == Color::BLACK && w->right->color == Color::BLACK) { w->color = Color::RED; x = x->parent; // 往上修复 } else { // case 3: 兄弟是黑色,且兄弟的右孩子是黑色,左孩子是红色 // -> 先把兄弟染红,左孩子染黑,然后右旋兄弟 // -> 转化为 case 4 if (w->right->color == Color::BLACK) { w->left->color = Color::BLACK; w->color = Color::RED; RotateRight(w); w = x->parent->right; // 更新兄弟 } // case 4: 兄弟是黑色,且兄弟的右孩子是红色 // -> 用兄弟替换父亲颜色,父亲染黑,兄弟的右孩子染黑 // -> 左旋父亲,修复完成,直接退出循环 w->color = x->parent->color; x->parent->color = Color::BLACK; w->right->color = Color::BLACK; RotateLeft(x->parent); x = root; // 结束循环 } } // 情况2:x 是右孩子(对称情况) else { TreeNode* w = x->parent->left; if (w->color == Color::RED) { w->color = Color::BLACK; x->parent->color = Color::RED; RotateRight(x->parent); w = x->parent->left; } if (w->right->color == Color::BLACK && w->left->color == Color::BLACK) { w->color = Color::RED; x = x->parent; } else { if (w->left->color == Color::BLACK) { w->right->color = Color::BLACK; w->color = Color::RED; RotateLeft(w); w = x->parent->left; } w->color = x->parent->color; x->parent->color = Color::BLACK; w->left->color = Color::BLACK; RotateRight(x->parent); x = root; } } } // 最后保证 x 是黑色(可能是根或者 nul) x->color = Color::BLACK; } template inline void RBTree::erase(const T& e) { TreeNode* z = find(e); //1-BST删除重置,找本节点右树最小或者左树最大 TreeNode* y = z; // 实际要删除的节点(可能是 z,也可能是 z 的后继) TreeNode* x; // y 的替代节点(可能是子节点,也可能是 nul) Color yOriginalColor = y->color; // 记录 y 的原始颜色,决定是否需要 fixdelete // case 1: z 没有左子树 -> 用右子树替代 z if (z->left == nul) { x = z->right; // 替代节点 // 把 z 从父亲断开 if (z->parent == nul) root = x; else if (z == z->parent->left) z->parent->left = x; else z->parent->right = x; x->parent = z->parent; } // case 2: z 没有右子树 -> 用左子树替代 z else if (z->right == nul) { x = z->left; if (z->parent == nul) root = x; else if (z == z->parent->left) z->parent->left = x; else z->parent->right = x; x->parent = z->parent; } // case 3: z 左右孩子都有 -> 找到 z 的中序后继 else { // 找 z 的后继(右子树最左节点) y = z->right; while (y->left != nul) y = y->left; yOriginalColor = y->color; // 记录后继的颜色 x = (y->right != nul ? y->right : nul); // 后继的右孩子作为替代 // 如果 y 不是 z 的直接右孩子 if (y->parent != z) { // 把 y->right 替代 y if (y->parent->left == y) y->parent->left = x; else y->parent->right = x; x->parent = y->parent; // 把 z->right 挂到 y 的右子树 y->right = z->right; y->right->parent = y; } // 把 z->left 挂到 y 的左子树 if (z->parent == nul) root = y; else if (z == z->parent->left) z->parent->left = y; else z->parent->right = y; y->parent = z->parent; y->left = z->left; y->left->parent = y; y->color = z->color; } delete z; //2-RBT性质重置 // 如果删除的实际节点是黑色,可能破坏红黑树性质 → fixdelete if (yOriginalColor == Color::BLACK) { fixdelete(x); } } template inline TreeNode* RBTree::find(const T& e) { TreeNode* p = root; while (p != nul) { if (e < p->element) p = p->left; else if (e > p->element) p = p->right; else break; } if (!p) p = nul; return p; } /* 推荐写法 if (x->parent == x->parent->parent->left) { // 父在左 TreeNode* y = x->parent->parent->right; // 叔叔 if (y->color == Color::RED) { // Case 1: 叔红 x->parent->color = Color::BLACK; y->color = Color::BLACK; x->parent->parent->color = Color::RED; x = x->parent->parent; // 上移祖父 } else { if (x == x->parent->right) { // Case 2: LR x = x->parent; RotateLeft(x); } // Case 3: LL x->parent->color = Color::BLACK; x->parent->parent->color = Color::RED; RotateRight(x->parent->parent); } 按照顺序写,这里可以看else(父亲为右节点)的思路 */