添加左右旋

This commit is contained in:
建峰 2024-06-23 21:15:48 +08:00
parent 26245288cc
commit f13b0d00aa
2 changed files with 148 additions and 1 deletions

View File

@ -102,9 +102,16 @@ struct _tree
// kernel
bool (*insert)(struct _tree* self, void* obj);
bool (*delete)(struct _tree* self, void* obj);
bool (*peek)(struct _tree* self, void** obj);
struct _tree_node* (*find)(struct _tree* self, void* obj);
struct _tree_node* (*find_min)(struct _tree* self);
struct _tree_node* (*find_max)(struct _tree* self);
bool (*rebalance)(struct _tree* self, struct _tree_node* root);
uint32_t (*height)(struct _tree* self, struct _tree_node* root);
bool (*min)(struct _tree* self, void** obj);
bool (*max)(struct _tree* self, void** obj);
bool (*clear)(struct _tree* self);
bool (*empty)(struct _tree* self);

View File

@ -1402,6 +1402,144 @@ static bool tree_rebalance(ptree_t head, ptree_node_t tree)
#endif
static struct _tree_node* tree_turn_left(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
assert(root->right != NULL);
struct _tree_node* node = root->right;
root->parent->right = node; // step1
node->parent = root->parent; // step2
root->parent = node; // step3
node->left = root; // step4
root->balance = 0;
node->balance = 0;
return node;
}
static struct _tree_node* tree_turn_right(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
assert(root->left != NULL);
struct _tree_node* node = root->left;
root->parent->left = node; // step1
node->parent = root->parent; // step2
root->parent = node; // step3
node->right = root; // step4
root->balance = 0;
node->balance = 0;
return node;
}
static struct _tree_node* tree_trun_left_then_right(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
assert(root->left != NULL);
struct _tree_node* node = root->left;
tree_turn_left(self, root->left);
node = tree_turn_right(self, root);
return node;
}
static struct _tree_node* tree_trun_right_then_left(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
assert(root->right != NULL);
struct _tree_node* node = root->right;
tree_turn_right(self, root->right);
node = tree_turn_left(self, root);
return node;
}
uint32_t tree_height(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
if(root == NULL)
{
return 0;
}
uint32_t left = tree_height(self, root->left);
uint32_t right = tree_height(self, root->right);
if(left > right)
{
return left + 1;
}
else
{
return right + 1;
}
}
static void tree_set_balance(struct _tree* self, struct _tree_node * node)
{
assert(self != NULL);
if(node == NULL)
{
return;
}
node->balance = self->height(self, node->right) - self->height(self, node->left);
}
/**
* @brief
*
* balance = rigth - left
*
* | | root->balance | node->balance | |
* | ---- | ------------ | -------------- | -------- |
* | 1 | > 0 | > 0 |
* | 2 | > 0 | < 0 |
* | 3 | < 0 | < 0 |
* | 4 | < 0 | > 0 |
*
* @param self
* @return true
* @return false
*/
static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
if((root == NULL) || (root->left == NULL) || (root->right == NULL))
{
return true;
}
int balance = root->balance;
if(balance > 0)
{
if(root->right->balance > 0)
{
root = tree_turn_left(self, root);
}
else if(root->right->balance < 0)
{
root = tree_trun_left_then_right(self, root);
}
}
else if(balance < 0)
{
if(root->left->balance < 0)
{
root = tree_turn_right(self, root);
}
else if(root->left->balance > 0)
{
root = tree_trun_right_then_left(self, root);
}
}
tree_set_balance(self, root);
return true;
}
static struct _tree_node * tree_node_new(struct _tree* self, void* obj)
{
@ -1778,6 +1916,8 @@ bool tree_avl_init(struct _tree *self, uint32_t obj_size)
self->breadth = tree_avl_breadth;
self->order = tree_order;
self->find = tree_avl_find;
self->height = tree_height;
self->rebalance = tree_avl_rebalance;
self->_root = NULL;