#include /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /** * @brief 内部辅助:安全检测某个节点的父链接是否为红 */ C_STATIC_FORCE_INLINE bool c_RBBST_IsRed(const c_RBBSTNode_t* node) { if (node == NULL) return C_RB_BLACK; // 空链接恒为黑色链接 return node->color == C_RB_RED; } /** * @brief 内部平衡机制 1:左旋操作 * * 将任意临时的右倾红链接,通过局部拓扑对调,安全置换为标准合规的左倾红链接 */ C_STATIC_FORCE_INLINE void c_RBBST_RotateLeft(c_RBBSTNode_t** node_ptr) { c_RBBSTNode_t* h = *node_ptr; c_RBBSTNode_t* x = h->right; h->right = x->left; x->left = h; x->color = h->color; h->color = C_RB_RED; *node_ptr = x; // 代理写回父节点 } /** * @brief 内部平衡机制 2:右旋操作 * * 临时放宽左侧的连续红链接,为后续的 4-node 拆分做前置拓扑对调准备 */ C_STATIC_FORCE_INLINE void c_RBBST_RotateRight(c_RBBSTNode_t** node_ptr) { c_RBBSTNode_t* h = *node_ptr; c_RBBSTNode_t* x = h->left; h->left = x->right; x->right = h; x->color = h->color; h->color = C_RB_RED; *node_ptr = x; } /** * @brief 内部平衡机制 3:颜色翻转(分解临时的 4-node 节点) */ C_STATIC_FORCE_INLINE void c_RBBST_FlipColors(c_RBBSTNode_t* h) { h->color = !h->color; if (h->left) h->left->color = !h->left->color; if (h->right) h->right->color = !h->right->color; } /** * @brief 内部递归插入与自适应动态平衡状态机 */ static c_err_t c_RedBlackBST_InternalPut(c_RedBlackBST_t* self, c_RBBSTNode_t** node_ptr, const void* key, const void* val, bool* is_new_inserted) { c_RBBSTNode_t* curr = *node_ptr; // 递归基:开辟挂载新节点,新生成的链接默认为极其活跃的【红链接】 if (curr == NULL) { c_RBBSTNode_t* new_node = (c_RBBSTNode_t*)c_Allocator_Alloc(&self->allocator, sizeof(c_RBBSTNode_t)); void* new_key = c_Allocator_Alloc(&self->allocator, self->key_size); void* new_val = c_Allocator_Alloc(&self->allocator, self->val_size); if (!new_node || !new_key || !new_val) { if (new_node) c_Allocator_Free(&self->allocator, new_node); if (new_key) c_Allocator_Free(&self->allocator, new_key); if (new_val) c_Allocator_Free(&self->allocator, new_val); return C_ERR_NOMEM; } memcpy(new_key, key, self->key_size); memcpy(new_val, val, self->val_size); new_node->key = new_key; new_node->val = new_val; new_node->left = NULL; new_node->right = NULL; new_node->color = C_RB_RED; // 🌟 核心:新节点一律为红链接 *node_ptr = new_node; *is_new_inserted = true; return C_ERR_OK; } int cmp_res = self->cmp(key, curr->key, self->args); c_err_t err = C_ERR_OK; if (cmp_res < 0) { err = c_RedBlackBST_InternalPut(self, &(curr->left), key, val, is_new_inserted); } else if (cmp_res > 0) { err = c_RedBlackBST_InternalPut(self, &(curr->right), key, val, is_new_inserted); } else { // 键已存在,执行覆写 memcpy(curr->val, val, self->val_size); *is_new_inserted = false; return C_ERR_OK; } if (err != C_ERR_OK) return err; // 🌟🌟🌟【左倾红黑树自适应自平衡标准控制链(Sedgewick 经典三部曲)】🌟🌟🌟 // 指针可能随着旋转被改写,故直接对当前二级指针接管的实体执行自底向上回溯刷新 // 步骤 1:若右链接为红且左链接为黑,强制执行左旋使其左倾 if (c_RBBST_IsRed((*node_ptr)->right) && !c_RBBST_IsRed((*node_ptr)->left)) { c_RBBST_RotateLeft(node_ptr); } // 步骤 2:若左链接为红,且左子节点的左链接也是红(连续两条红链接出现),强制执行右旋平衡 if (c_RBBST_IsRed((*node_ptr)->left) && c_RBBST_IsRed((*node_ptr)->left->left)) { c_RBBST_RotateRight(node_ptr); } // 步骤 3:若左右两条子链接同为红,强制翻转颜色,将红链接推向更高的父层级 if (c_RBBST_IsRed((*node_ptr)->left) && c_RBBST_IsRed((*node_ptr)->right)) { c_RBBST_FlipColors(*node_ptr); } return C_ERR_OK; } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ c_err_t c_RedBlackBST_Init(c_RedBlackBST_t* self, c_size_t key_size, c_size_t val_size, c_SortCompare_t cmp, void* args, c_Allocator_t* allocator) { if (!self || key_size == 0 || val_size == 0 || !cmp) { return C_ERR_PARAM; } if (allocator) { self->allocator = *allocator; } else { self->allocator = c_DefaultAllocator; } self->root = NULL; self->size = 0; self->key_size = key_size; self->val_size = val_size; self->cmp = cmp; self->args = args; return C_ERR_OK; } /** * @brief 存入键值对(始终维持树的对数级绝对平衡,时间复杂度 O(log N)) */ c_err_t c_RedBlackBST_Put(c_RedBlackBST_t* self, const void* key, const void* val) { if (!self || !key || !val) return C_ERR_PARAM; bool is_new = false; c_err_t err = c_RedBlackBST_InternalPut(self, &(self->root), key, val, &is_new); if (err == C_ERR_OK) { if (is_new) self->size++; // 根节点的父链接在扩容和旋转后必须强制恢复回稳定严肃的【黑链接】 self->root->color = C_RB_BLACK; } return err; } /** * @brief 精准二叉有序检索(时间复杂度稳定为 O(log N)) */ c_err_t c_RedBlackBST_Get(const c_RedBlackBST_t* self, const void* key, void* out_val) { if (!self || !key || !out_val) return C_ERR_PARAM; c_RBBSTNode_t* curr = self->root; while (curr != NULL) { int cmp_res = self->cmp(key, curr->key, self->args); if (cmp_res < 0) curr = curr->left; else if (cmp_res > 0) curr = curr->right; else { memcpy(out_val, curr->val, self->val_size); return C_ERR_OK; } } return C_ERR_NOTFOUND; } /** * @brief 检查树中是否有效包含指定的 Key */ bool c_RedBlackBST_Contains(const c_RedBlackBST_t* self, const void* key) { if (!self || !key) return false; c_RBBSTNode_t* curr = self->root; while (curr != NULL) { int cmp_res = self->cmp(key, curr->key, self->args); if (cmp_res < 0) curr = curr->left; else if (cmp_res > 0) curr = curr->right; else return true; } return false; } static void c_RedBlackBST_InternalDeinit(c_Allocator_t* alloc, c_RBBSTNode_t* node) { if (node == NULL) return; c_RedBlackBST_InternalDeinit(alloc, node->left); c_RedBlackBST_InternalDeinit(alloc, node->right); c_Allocator_Free(alloc, node->key); c_Allocator_Free(alloc, node->val); c_Allocator_Free(alloc, node); } /** * @brief 彻底销毁红黑树并逆向释放全部堆资源 */ void c_RedBlackBST_Destroy(c_RedBlackBST_t* self) { if (self && self->root) { c_RedBlackBST_InternalDeinit(&self->allocator, self->root); self->root = NULL; self->size = 0; } } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /** * @brief 自底向上沿途修复平衡(Fix-up) */ static void c_RBBST_Balance(c_RBBSTNode_t** node_ptr) { if (*node_ptr == NULL) return; // 1. 纠正右倾红链接 if (c_RBBST_IsRed((*node_ptr)->right) && !c_RBBST_IsRed((*node_ptr)->left)) { c_RBBST_RotateLeft(node_ptr); } // 2. 纠正连续红链接 if (c_RBBST_IsRed((*node_ptr)->left) && c_RBBST_IsRed((*node_ptr)->left->left)) { c_RBBST_RotateRight(node_ptr); } // 3. 分解临时的 4-node if (c_RBBST_IsRed((*node_ptr)->left) && c_RBBST_IsRed((*node_ptr)->right)) { c_RBBST_FlipColors(*node_ptr); } } /** * @brief 假设当前节点 h 为红且 h->left 和 h->left->left 都为黑,将红链接强制向左移动 */ static void c_RBBST_MoveRedLeft(c_RBBSTNode_t** node_ptr) { c_RBBSTNode_t* h = *node_ptr; c_RBBST_FlipColors(h); // 如果亲兄弟节点的左子节点是红链接,说明可以向右边“借”一个红链接过来 if (c_RBBST_IsRed(h->right->left)) { c_RBBST_RotateRight(&(h->right)); c_RBBST_RotateLeft(node_ptr); // 旋转后由于指针载体换成新根,同步对其刷新颜色翻转 c_RBBST_FlipColors(*node_ptr); } } /** * @brief 假设当前节点 h 为红且 h->right 和 h->right->left 都为黑,将红链接强制向右移动 */ static void c_RBBST_MoveRedRight(c_RBBSTNode_t** node_ptr) { c_RBBSTNode_t* h = *node_ptr; c_RBBST_FlipColors(h); // 如果亲兄弟节点的左子节点是红链接,说明可以向左边“借”一个红链接过来 if (c_RBBST_IsRed(h->left->left)) { c_RBBST_RotateRight(node_ptr); c_RBBST_FlipColors(*node_ptr); } } /** * @brief 内部辅助:寻找指定子树的绝对最小值节点(内部删除并解绑提取) */ static c_RBBSTNode_t* c_RedBlackBST_InternalDeleteMin(c_RedBlackBST_t* self, c_RBBSTNode_t** node_ptr) { c_RBBSTNode_t* curr = *node_ptr; if (curr->left == NULL) { *node_ptr = NULL; // 断开断裂 return curr; } // 核心推进:如果当前左子链和左子的左子都是黑色链接,为了防止删除 2-node 崩溃,强行将红链接左推 if (!c_RBBST_IsRed(curr->left) && !c_RBBST_IsRed(curr->left->left)) { c_RBBST_MoveRedLeft(node_ptr); } c_RBBSTNode_t* min_node = c_RedBlackBST_InternalDeleteMin(self, &((*node_ptr)->left)); // 自底向上逐级退栈平衡修复 c_RBBST_Balance(node_ptr); return min_node; } /** * @brief 内部递归自适应删除核心逻辑 */ static c_err_t c_RedBlackBST_InternalDelete(c_RedBlackBST_t* self, c_RBBSTNode_t** node_ptr, const void* key) { c_RBBSTNode_t* curr = *node_ptr; if (curr == NULL) { return C_ERR_NOTFOUND; } // 1. 如果目标键小于当前节点,向左子树探查 if (self->cmp(key, curr->key, self->args) < 0) { // 如果左边深度不足,前置借调红链接向左推 if (!c_RBBST_IsRed(curr->left) && !c_RBBST_IsRed(curr->left->left)) { c_RBBST_MoveRedLeft(node_ptr); } c_err_t err = c_RedBlackBST_InternalDelete(self, &((*node_ptr)->left), key); c_RBBST_Balance(node_ptr); // 退栈修复 return err; } else { // 2. 如果当前左子链接是红的,强制右旋。 // 这可以让待比较的较大或相等的元素被顺利挪动并暴露到右侧 if (c_RBBST_IsRed(curr->left)) { c_RBBST_RotateRight(node_ptr); curr = *node_ptr; // 刷新本地缓存指针 } // 3. 精确命中检查条件:如果完全相等,且已经走到了树的叶子底部(无右子树) // 此时由于自顶向下红链接移位的保护,curr 必然含有红链接,可以直接抹除并释放 if (self->cmp(key, curr->key, self->args) == 0 && (curr->right == NULL)) { c_RBBSTNode_t* old_node = curr; *node_ptr = curr->left; // 让左子树托管 c_Allocator_Free(&self->allocator, old_node->key); c_Allocator_Free(&self->allocator, old_node->val); c_Allocator_Free(&self->allocator, old_node); return C_ERR_OK; } // 4. 继续向右子树探查(目标比当前大,或者相等但处于中间层级) if (!c_RBBST_IsRed(curr->right) && !c_RBBST_IsRed(curr->right->left)) { c_RBBST_MoveRedRight(node_ptr); curr = *node_ptr; } // 5. 中间层级精确命中:执行 Hibbard 后继者替换策略 if (self->cmp(key, curr->key, self->args) == 0) { c_RBBSTNode_t* old_node = curr; // 剥离并索取右子树的绝对最小值节点作为继承人 c_RBBSTNode_t* successor = c_RedBlackBST_InternalDeleteMin(self, &(curr->right)); // 继承人完美承接原有乱序节点的所有双向指针拓扑以及红黑颜色 successor->left = old_node->left; successor->right = (*node_ptr)->right; successor->color = old_node->color; *node_ptr = successor; // 代理顶替 // 彻底释放旧节点占用的内存 c_Allocator_Free(&self->allocator, old_node->key); c_Allocator_Free(&self->allocator, old_node->val); c_Allocator_Free(&self->allocator, old_node); c_RBBST_Balance(node_ptr); return C_ERR_OK; } else { // 只是普通的向右边路探查 c_err_t err = c_RedBlackBST_InternalDelete(self, &((*node_ptr)->right), key); c_RBBST_Balance(node_ptr); return err; } } } /** * @brief 根据指定 Key 彻底从左倾红黑树中斩断删除该节点(时间复杂度卡死在完美的 O(log N) 上限) */ c_err_t c_RedBlackBST_Delete(c_RedBlackBST_t* self, const void* key) { if (!self || !key) { return C_ERR_PARAM; } // 状态码规范链条:空仓异常前置拦截 if (self->size == 0 || self->root == NULL) { return C_ERR_EMPTY; } c_err_t err = c_RedBlackBST_InternalDelete(self, &(self->root), key); if (err == C_ERR_OK) { self->size--; // 如果树还没被删空,必须对重组后的最终新树根强制刷新并恢复黑高性质 `'B'` if (self->root != NULL) { self->root->color = C_RB_BLACK; } } return err; }