From e3f59e2b908a215e611825ca4e7331a3a864d51c Mon Sep 17 00:00:00 2001 From: wjf-hs Date: Mon, 1 Jul 2024 11:09:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AAbug?= =?UTF-8?q?=EF=BC=8C=E7=BA=A2=E9=BB=91=E6=A0=91=E7=9A=84=E5=B7=A6=E5=8F=B3?= =?UTF-8?q?=E6=97=8B=E7=9B=B4=E6=8E=A5=E8=B0=83=E7=94=A8=E4=BA=86AVL?= =?UTF-8?q?=E6=A0=91=E7=9A=84=E5=B7=A6=E5=8F=B3=E6=97=8B=E8=BD=AC=EF=BC=8C?= =?UTF-8?q?=E9=87=8C=E9=9D=A2=E6=9C=89=E5=B9=B3=E8=A1=A1=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E8=AE=BE=E7=BD=AE=EF=BC=8C=E5=AF=BC=E8=87=B4=E5=86=B2?= =?UTF-8?q?=E7=AA=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tree.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/src/tree.c b/src/tree.c index cfe84e9..8f389b0 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1062,6 +1062,80 @@ bool tree_set_color(struct _tree_node* node, rbt_color color) } +static struct _tree_node* tree_rb_turn_left(struct _tree* self, struct _tree_node* root) +{ + assert(self != NULL); + assert(root != NULL); + struct _tree_node* node = root->right; + if(node == NULL) + { + return root; + } + + if(root->parent == NULL) + { + self->_root = node; // step1 + } + else + { + if(root->parent->left == root) + { + root->parent->left = node; // step1 + } + else if(root->parent->right == root) + { + root->parent->right = node; // setp1 + } + } + node->parent = root->parent; // step2 + root->parent = node; // step3 + + root->right = node->left; // step4 + if(node->left != NULL) + { + node->left->parent = root; // step5 + } + node->left = root; // step6 + return node; +} + +static struct _tree_node* tree_rb_turn_right(struct _tree* self, struct _tree_node* root) +{ + assert(self != NULL); + assert(root != NULL); + struct _tree_node* node = root->left; + if(node == NULL) + { + return root; + } + + if(root->parent == NULL) + { + self->_root = node; // step1 + } + else + { + if(root->parent->left == root) + { + root->parent->left = node; // step1 + } + else if(root->parent->right == root) + { + root->parent->right = node; // setp1 + } + } + node->parent = root->parent; // step2 + root->parent = node; // step3 + + root->left = node->right; // step4 + if(node->right != NULL) + { + node->right->parent = root; // step5 + } + node->right = root; // step6 + return node; +} + bool tree_rb_insert(struct _tree* self, void* obj) { assert(self != NULL); @@ -1167,11 +1241,11 @@ static bool tree_rb_rebalance(struct _tree* self, struct _tree_node* node) { if(node == father->right) { - node = tree_turn_left(self, father); + node = tree_rb_turn_left(self, father); } father->color = RBT_BLACK; grandfather->color = RBT_RED; - node = tree_turn_right(self, grandfather); + node = tree_rb_turn_right(self, grandfather); break; } } @@ -1189,11 +1263,11 @@ static bool tree_rb_rebalance(struct _tree* self, struct _tree_node* node) { if(node == father->left) { - node = tree_turn_right(self, father); + node = tree_rb_turn_right(self, father); } father->color = RBT_BLACK; grandfather->color = RBT_RED; - node = tree_turn_left(self, grandfather); + node = tree_rb_turn_left(self, grandfather); break; } } @@ -1233,7 +1307,7 @@ bool tree_rb_delete_fix(struct _tree* self, struct _tree_node* node) // so ... brother->color = RBT_BLACK; father->color = RBT_RED; - tmp = tree_turn_left(self, father); + tmp = tree_rb_turn_left(self, father); // After deleting the node, it became unbalanced // so convert to case5 } @@ -1243,7 +1317,7 @@ bool tree_rb_delete_fix(struct _tree* self, struct _tree_node* node) brother->color = father->color; father->color = RBT_BLACK; brother->right->color = RBT_BLACK; - node = tree_turn_left(self, father); + node = tree_rb_turn_left(self, father); // After deleting the node, it remains balanced break; } @@ -1252,7 +1326,7 @@ bool tree_rb_delete_fix(struct _tree* self, struct _tree_node* node) // case 3 brother->color = RBT_RED; brother->left->color = RBT_BLACK; - tmp = tree_turn_right(self, brother); + tmp = tree_rb_turn_right(self, brother); // Convert to case2 } else @@ -1268,6 +1342,8 @@ bool tree_rb_delete_fix(struct _tree* self, struct _tree_node* node) else { // case 5 + // father is red, brother has no children + // if delete the node, it remains balanced brother->color = RBT_RED; father->color = RBT_BLACK; break; @@ -1283,7 +1359,7 @@ bool tree_rb_delete_fix(struct _tree* self, struct _tree_node* node) // case1 brother->color = RBT_BLACK; father->color = RBT_RED; - tmp = tree_turn_right(self, father); + tmp = tree_rb_turn_right(self, father); } else if(brother->left != NULL && brother->left->color == RBT_RED) { @@ -1291,7 +1367,7 @@ bool tree_rb_delete_fix(struct _tree* self, struct _tree_node* node) brother->color = father->color; father->color = RBT_BLACK; brother->left->color = RBT_BLACK; - node = tree_turn_right(self, father); + node = tree_rb_turn_right(self, father); break; } else if(brother->right != NULL && brother->right->color == RBT_RED) @@ -1299,7 +1375,7 @@ bool tree_rb_delete_fix(struct _tree* self, struct _tree_node* node) // case3 brother->color = RBT_RED; brother->right->color = RBT_BLACK; - tmp = tree_turn_left(self, brother); + tmp = tree_rb_turn_left(self, brother); // convert to case2 } else @@ -1386,7 +1462,7 @@ bool tree_rb_delete(struct _tree* self, void* obj) if(tmp->color == RBT_BLACK) { tree_rb_delete_fix(self, tmp); - } + } if(tmp->parent != NULL) {