unicstl/src/tree.c
2024-06-25 18:16:07 +08:00

1217 lines
27 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file tree.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2024-06-23
*
* @copyright Copyright (c) 2024
*
*/
#include "tree.h"
#include "queue.h"
#include "stack.h"
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);
}
static struct _tree_node* tree_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
tree_set_balance(self, root);
tree_set_balance(self, node);
return node;
}
static struct _tree_node* tree_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
tree_set_balance(self, root);
tree_set_balance(self, node);
return node;
}
static struct _tree_node* tree_turn_left_then_right(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
struct _tree_node* node = root->left;
if(node != NULL)
{
tree_turn_left(self, node);
}
node = tree_turn_right(self, root);
return node;
}
static struct _tree_node* tree_turn_right_then_left(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
assert(root != NULL);
struct _tree_node* node = root->right;
if(node != NULL)
{
tree_turn_right(self, node);
}
node = tree_turn_left(self, root);
return node;
}
int32_t tree_height(struct _tree* self, struct _tree_node* root)
{
#if 0
assert(self != NULL);
if(root == NULL)
{
return 0;
}
int32_t left_height = tree_height(self, root->left);
int32_t right_height = tree_height(self, root->right);
return (left_height > right_height) ? (left_height + 1) : (right_height + 1);
#else
assert(self != NULL);
if(root == NULL)
{
return 0;
}
int32_t height = 0;
int32_t count_cur_level = 0;
int32_t count_next_level = 0;
struct _tree_node* node = root;
queue_t queue = queue_new();
queue_init(queue, sizeof(struct _tree_node*));
queue->push(queue, &node);
while(!queue->empty(queue))
{
queue->pop(queue, &node);
if(node->left != NULL)
{
queue->push(queue, &node->left);
}
if(node->right != NULL)
{
queue->push(queue, &node->right);
}
if(count_cur_level == count_next_level)
{
count_next_level = queue->size(queue);
height++;
count_cur_level = 1;
}
else
{
count_cur_level++;
}
}
queue_free(queue);
return height;
#endif
}
/**
* @brief
*
* <20><> balance = rigth - left Ϊ<><CEAA>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* | <20><><EFBFBD><EFBFBD> | root->balance | node->balance | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ |
* | ---- | ------------ | -------------- | -------- |
* | 1 | 2 | >= 0 | <20><><EFBFBD><EFBFBD>
* | 2 | 2 | < 0 | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* | 3 | -2 | <= 0 | <20><><EFBFBD><EFBFBD>
* | 4 | -2 | > 0 | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param self
* @return true
* @return false
*/
static bool tree_avl_rebalance(struct _tree* self, struct _tree_node* root)
{
#if 0
assert(self != NULL);
if(root == NULL)
{
return false;
}
if(root->left == NULL && root->right == NULL)
{
return false;
}
// self->print_obj(root->obj);
tree_set_balance(self, root);
int balance = root->balance;
if(balance == 2)
{
if(root->right->balance >= 0)
{
root = tree_turn_left(self, root);
}
else
{
root = tree_turn_right_then_left(self, root);
}
}
else if(balance == -2)
{
if(root->left->balance <= 0)
{
root = tree_turn_right(self, root);
}
else
{
root = tree_turn_left_then_right(self, root);
}
}
if(root->parent != NULL)
{
tree_avl_rebalance(self, root->parent);
}
else
{
self->_root = root;
}
return true;
#else
assert(self != NULL);
if(root == NULL)
{
return false;
}
if(root->left == NULL && root->right == NULL)
{
return false;
}
int balance = 0;
do
{
tree_set_balance(self, root);
balance = root->balance;
if(balance == 2)
{
if(root->right->balance >= 0)
{
root = tree_turn_left(self, root);
}
else
{
root = tree_turn_right_then_left(self, root);
}
}
else if(balance == -2)
{
if(root->left->balance <= 0)
{
root = tree_turn_right(self, root);
}
else
{
root = tree_turn_left_then_right(self, root);
}
}
// if node become the new root
if(root->parent == NULL)
{
break;
}
root = root->parent;
}while(root != NULL);
self->_root = root;
return true;
#endif
}
static struct _tree_node * tree_node_new(struct _tree* self, void* obj)
{
assert(self != NULL);
void * obj_new = malloc(self->_obj_size);
if (obj_new == NULL)
{
goto done;
}
memmove(obj_new, obj, self->_obj_size);
struct _tree_node* node_new = (struct _tree_node*)malloc(sizeof(struct _tree_node));
if(node_new == NULL)
{
goto done;
}
node_new->obj = obj_new;
node_new->parent = NULL;
node_new->left = NULL;
node_new->right = NULL;
node_new->balance = 0;
return node_new;
done:
if(obj_new != NULL)
{
free(obj_new);
}
if(node_new != NULL)
{
free(node_new);
}
return NULL;
}
static bool tree_node_free(struct _tree_node* node)
{
if(node != NULL)
{
if(node->obj != NULL)
{
free(node->obj);
}
free(node);
}
return true;
}
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2>Ҳ<EFBFBD><D2B2><EFBFBD>λ<EFBFBD><CEBB>
*
* @param self <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
* @param obj Ҫ<><D2AA><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>
*/
struct _tree_node * tree_find_pos(struct _tree* self, void* obj)
{
assert(self != NULL);
assert(self->compare != NULL);
struct _tree_node* root = self->_root;
while(root != NULL)
{
if(self->compare(obj, root->obj) == 0)
{
break;
}
else if(self->compare(obj, root->obj) < 0)
{
if(root->left == NULL)
{
break;
}
root = root->left;
}
else
{
if(root->right == NULL)
{
break;
}
root = root->right;
}
}
return root;
}
bool tree_avl_insert(struct _tree* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
assert(self->compare != NULL);
struct _tree_node* node = tree_node_new(self, obj);
if(node == NULL)
{
return false;
}
// if no root
if(self->_root == NULL)
{
self->_root = node;
}
else
{
// insert the node
struct _tree_node* root = tree_find_pos(self, obj);
if(self->compare(obj, root->obj) < 0)
{
root->left = node;
node->parent = root;
}
else if(self->compare(obj, root->obj) > 0)
{
root->right = node;
node->parent = root;
}
else
{
// if obj exist, just return false
tree_node_free(node);
return false;
}
self->rebalance(self, root);
}
self->_size++;
return true;
}
static bool tree_avl_delete_single_child(struct _tree* self, struct _tree_node* node)
{
assert(self != NULL);
assert(node != NULL);
if(node->parent == NULL)
{
if(node->left != NULL)
{
node->left->parent = node->parent; // step1 : NULL for root
self->_root = node->left; // step2
}
else if(node->right != NULL)
{
node->right->parent = node->parent; // step1 : NULL for root
self->_root = node->right; // step2
}
else
{
self->_root = NULL;
}
}
else
{
if(node->parent->left == node)
{
if(node->left != NULL)
{
node->left->parent = node->parent; // step1
node->parent->left = node->left; // step2
}
else if(node->right != NULL)
{
node->right->parent = node->parent; // step1
node->parent->left = node->right; // step2
}
else
{
node->parent->left = NULL;
}
}
else if(node->parent->right == node)
{
if(node->left != NULL)
{
node->left->parent = node->parent; // step1
node->parent->right = node->left; // step2
}
else if(node->right != NULL)
{
node->right->parent = node->parent; // step1
node->parent->right = node->right; // step2
}
else
{
node->parent->right = NULL;
}
}
self->rebalance(self, node->parent);
}
tree_node_free(node);
return true;
}
static bool tree_avl_delete_double_child(struct _tree* self, struct _tree_node* node)
{
assert(self != NULL);
assert(node != NULL);
struct _tree_node* tmp = self->find_min(self, node->right);
if(tmp != NULL)
{
memmove(node->obj, tmp->obj, self->_obj_size);
tree_avl_delete_single_child(self, tmp);
}
return true;
}
bool tree_avl_delete(struct _tree* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
assert(self->compare != NULL);
if(self->empty(self))
{
return false;
}
struct _tree_node* node = self->find(self, obj);
if(node == NULL)
{
return false;
}
if((node->left != NULL) && (node->right != NULL))
{
// have two child
tree_avl_delete_double_child(self, node);
}
else
{
// have singule child or no child
tree_avl_delete_single_child(self, node);
}
self->_size--;
return true;
}
struct _tree_node * tree_avl_find(struct _tree* self, void* obj)
{
assert(self != NULL);
struct _tree_node* root = self->_root;
while(root != NULL)
{
if(self->compare(obj, root->obj) == 0)
{
return root;
}
else if(self->compare(obj, root->obj) < 0)
{
root = root->left;
}
else
{
root = root->right;
}
}
return NULL;
}
bool tree_clear(struct _tree* self)
{
assert(self != NULL);
if(self->_root == NULL)
{
return false;
}
struct _tree_node* node = self->_root;
queue_t queue = queue_new();
queue_init(queue, sizeof(struct _tree_node*));
queue->push(queue, &node);
while(!queue->empty(queue))
{
queue->pop(queue, &node);
if(node->left != NULL)
{
queue->push(queue, &node->left);
}
if(node->right != NULL)
{
queue->push(queue, &node->right);
}
tree_node_free(node);
}
queue_free(queue);
self->_root = NULL;
self->_size = 0;
return true;
}
bool tree_empty(struct _tree* self)
{
assert(self != NULL);
return !self->size(self);
}
uint32_t tree_size(struct _tree* self)
{
assert(self != NULL);
return self->_size;
}
// free
void tree_destory(struct _tree* self)
{
assert(self != NULL);
self->clear(self);
self->_root = NULL;
}
void tree_order(struct _tree* self, bool right_priority)
{
assert(self != NULL);
self->_right_priority = right_priority;
}
void tree_avl_preorder(struct _tree* self, struct _tree_node* root)
{
#if 0
assert(self != NULL);
if(root == NULL)
{
return;
}
if(!self->_right_priority)
{
self->print_obj(root->obj);
if(root->left != NULL)
{
tree_avl_preorder(self, root->left);
}
if(root->right != NULL)
{
tree_avl_preorder(self, root->right);
}
}
else
{
self->print_obj(root->obj);
if(root->right != NULL)
{
tree_avl_preorder(self, root->right);
}
if(root->left != NULL)
{
tree_avl_preorder(self, root->left);
}
}
#else
assert(self != NULL);
if(root == NULL)
{
return;
}
struct _tree_node* node = root;
stack_t stack = stack_new();
stack_init(stack, sizeof(struct _tree_node*));
if(!self->_right_priority) // left priority
{
while(!stack->empty(stack) || node != NULL)
{
if(node != NULL)
{
self->print_obj(node->obj);
stack->push(stack, &node);
node = node->left;
}
else
{
stack->pop(stack, &node);
node = node->right;
}
}
}
else
{
while(!stack->empty(stack) || node != NULL)
{
if(node != NULL)
{
self->print_obj(node->obj);
stack->push(stack, &node);
node = node->right;
}
else
{
stack->pop(stack, &node);
node = node->left;
}
}
}
stack_free(stack);
#endif
}
void tree_avl_inorder(struct _tree* self, struct _tree_node* root)
{
#if 0
assert(self != NULL);
if(root == NULL)
{
return;
}
if(!self->_right_priority)
{
if(root->left != NULL)
{
tree_avl_inorder(self, root->left);
}
self->print_obj(root->obj);
if(root->right != NULL)
{
tree_avl_inorder(self, root->right);
}
}
else
{
if(root->right != NULL)
{
tree_avl_inorder(self, root->right);
}
self->print_obj(root->obj);
if(root->left != NULL)
{
tree_avl_inorder(self, root->left);
}
}
#else
assert(self != NULL);
if(root == NULL)
{
return;
}
struct _tree_node *node = root;
stack_t stack = stack_new();
stack_init(stack, sizeof(struct _tree_node*));
if(!self->_right_priority) // left priority
{
while(!stack->empty(stack) || node != NULL)
{
if(node != NULL)
{
stack->push(stack, &node);
node = node->left;
}
else
{
stack->pop(stack, &node);
self->print_obj(node->obj);
node = node->right;
}
}
}
else
{
while(node != NULL || !stack->empty(stack))
{
if(node != NULL)
{
stack->push(stack, &node);
node = node->right;
}
else
{
stack->pop(stack, &node);
self->print_obj(node->obj);
node = node->left;
}
}
}
stack_free(stack);
#endif
}
void tree_avl_postorder(struct _tree* self, struct _tree_node* root)
{
#if 0
assert(self != NULL);
if(root == NULL)
{
return;
}
if(!self->_right_priority)
{
if(root->left != NULL)
{
tree_avl_postorder(self, root->left);
}
if(root->right != NULL)
{
tree_avl_postorder(self, root->right);
}
self->print_obj(root->obj);
}
else
{
if(root->right != NULL)
{
tree_avl_postorder(self, root->right);
}
if(root->left != NULL)
{
tree_avl_postorder(self, root->left);
}
self->print_obj(root->obj);
}
#else
assert(self != NULL);
if(root == NULL)
{
return;
}
struct _tree_node* node = root;
stack_t stack2 = stack_new();
stack_init(stack2, sizeof(struct _tree_node*));
// because: left:postorder == right:the reverse of preorder
stack_t stack = stack_new();
stack_init(stack, sizeof(struct _tree_node*));
if(!self->_right_priority) // left priority
{
while(!stack->empty(stack) || node != NULL)
{
if(node != NULL)
{
stack2->push(stack2, &node);
stack->push(stack, &node);
node = node->right;
}
else
{
stack->pop(stack, &node);
node = node->left;
}
}
}
else
{
while(!stack->empty(stack) || node != NULL)
{
if(node != NULL)
{
stack2->push(stack2, &node);
stack->push(stack, &node);
node = node->left;
}
else
{
stack->pop(stack, &node);
node = node->right;
}
}
}
while(!stack2->empty(stack2))
{
stack2->pop(stack2, &node);
self->print_obj(node->obj);
}
stack_free(stack);
stack_free(stack2);
#endif
}
// traversal breadth
void tree_avl_breadth(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
if(root == NULL)
{
return;
}
struct _tree_node* node = root;
queue_t queue = queue_new();
queue_init(queue, sizeof(struct _tree_node*));
if(node != NULL)
{
queue->push(queue, &node);
while(!queue->empty(queue))
{
queue->pop(queue, &node);
if(!self->_right_priority)
{
if(node->left != NULL)
{
queue->push(queue, &node->left);
}
if(node->right != NULL)
{
queue->push(queue, &node->right);
}
}
else
{
if(node->right != NULL)
{
queue->push(queue, &node->right);
}
if(node->left != NULL)
{
queue->push(queue, &node->left);
}
}
self->print_obj(node->obj);
}
}
queue_free(queue);
}
static struct _tree_node* tree_find_min(struct _tree* self, struct _tree_node* root)
{
assert(self != NULL);
#if 0
if(root == NULL)
{
return NULL;
}
if(root->left == NULL)
{
return root;
}
return tree_find_min(self, root->left);
#else
while(root != NULL)
{
if(root->left != NULL)
{
root = root->left;
}
else
{
return root;
}
}
return root;
#endif
}
static struct _tree_node* tree_find_max(struct _tree* self, struct _tree_node* root)
{
#if 0
assert(self != NULL);
if(root == NULL)
{
return NULL;
}
if(root->right == NULL)
{
return root;
}
return tree_find_max(self, root->right);
#else
while(root != NULL)
{
if(root->right != NULL)
{
root = root->right;
}
else
{
return root;
}
}
return root;
#endif
}
bool tree_min(struct _tree* self, void* obj)
{
assert(self != NULL);
struct _tree_node* node = tree_find_min(self, self->_root);
if(node == NULL)
{
return false;
}
memmove(obj, node->obj, self->_obj_size);
return true;
}
bool tree_max(struct _tree* self, void* obj)
{
assert(self != NULL);
struct _tree_node* node = tree_find_max(self, self->_root);
if(node == NULL)
{
return false;
}
memmove(obj, node->obj, self->_obj_size);
return true;
}
bool tree_avl_init(struct _tree *self, uint32_t obj_size)
{
assert(self != NULL);
self->_obj_size = obj_size;
self->_size = 0;
// self->_capacity = 64;
// self->_ratio = 2;
self->_right_priority = false;
self->insert = tree_avl_insert;
self->delete = tree_avl_delete;
self->clear = tree_clear;
self->empty = tree_empty;
self->size = tree_size;
self->destory = tree_destory;
self->preorder = tree_avl_preorder;
self->inorder = tree_avl_inorder;
self->postorder = tree_avl_postorder;
self->breadth = tree_avl_breadth;
self->order = tree_order;
self->find = tree_avl_find;
self->height = tree_height;
self->rebalance = tree_avl_rebalance;
self->find_max = tree_find_max;
self->find_min = tree_find_min;
self->max = tree_max;
self->min = tree_min;
self->_root = NULL;
return true;
}
rbt_color tree_color(struct _tree_node* node)
{
assert(node != NULL);
return node->color;
}
bool tree_set_color(struct _tree_node* node, rbt_color color)
{
assert(node != NULL);
node->color = color;
return true;
}
/**
* @brief
*
* <20><> balance = rigth - left Ϊ<><CEAA>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* | <20><><EFBFBD><EFBFBD> | root->balance | node->balance | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ |
* | ---- | ------------ | -------------- | -------- |
* | 1 | 2 | >= 0 | <20><><EFBFBD><EFBFBD>
* | 2 | 2 | < 0 | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* | 3 | -2 | <= 0 | <20><><EFBFBD><EFBFBD>
* | 4 | -2 | > 0 | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param self
* @return true
* @return false
*/
static bool tree_rb_rebalance(struct _tree* self, struct _tree_node* node)
{
assert(self != NULL);
if(node == NULL)
{
return false;
}
struct _tree_node* father = NULL;
struct _tree_node* grandfather = NULL;
struct _tree_node* uncle = NULL;
/**
* @brief <20>²<EFBFBD><C2B2><EFBFBD><EFBFBD>ڵ<EFBFBD>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD><C9AB><EFBFBD>Ҹ<EFBFBD><D2B8>ڵ<EFBFBD>Ϊ<EFBFBD><CEAA>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><C2A3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[1-3]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[4-6]<5D>ԳƲ<D4B3><C6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* ԭ<><D4AD>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>취ά<ECB7A8>ֺ<EFBFBD><D6BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲ<EFBFBD><CAB2><EFBFBD>
*
* | <20><><EFBFBD><EFBFBD> | ˵<><CBB5> | <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ |
* | ---- | --- | -------- |
* | 0 | <20><><EFBFBD>ڵ<EFBFBD>Ϊ<EFBFBD><CEAA>ɫ | <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
* | 1 | <20><><EFBFBD>ү<ECA3AC>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD> | <20><><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD><EFBFBD>ڣ<EFBFBD>ү<EFBFBD><EFBFBD><ECA3AC><EFBFBD><EFBFBD>
* | 2 | <20><><EFBFBD>ү<ECA3AC>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD> | <20><><EFBFBD><EFBFBD>ү<EFBFBD><D2AF><EFBFBD><EFBFBD>ͬһ<CDAC>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD>ڣ<EFBFBD>ү<EFBFBD>ү<ECA3AC><D2AF>/<2F><><EFBFBD><EFBFBD>
* | 3 | <20><><EFBFBD>ү<ECA3AC>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD> | <20><><EFBFBD><EFBFBD>ү<EFBFBD><D2AF><EFBFBD>ڲ<EFBFBD>ͬ<EFBFBD>ߣ<EFBFBD><DFA3>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¸<EFBFBD><C2B8><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD>ү<EFBFBD>ү<ECA3AC><D2AF>/<2F><><EFBFBD><EFBFBD>
*/
while(node->parent != NULL && node->parent->color == RBT_RED)
{
father = node->parent;
grandfather = father->parent;
if(father == grandfather->left)
{
uncle = grandfather->right;
if(uncle != NULL && uncle->color == RBT_RED) // uncle is red
{
father->color = RBT_BLACK;
uncle->color = RBT_BLACK;
grandfather->color = RBT_RED;
node = grandfather;
}
else // uncle is black
{
if(node == father->right)
{
node = tree_turn_left(self, father);
node->color = RBT_BLACK;
}
else
{
father->color = RBT_BLACK;
}
grandfather->color = RBT_RED;
tree_turn_right(self, grandfather);
break;
}
}
else
{
uncle = grandfather->left;
if(uncle != NULL && uncle->color == RBT_RED) // uncle is red
{
father->color = RBT_BLACK;
uncle->color = RBT_BLACK;
grandfather->color = RBT_RED;
node = grandfather;
}
else // uncle is black
{
if(node == father->left)
{
node = tree_turn_right(self, father);
node->color = RBT_BLACK;
}
else
{
father->color = RBT_BLACK;
}
grandfather->color = RBT_RED;
tree_turn_left(self, grandfather);
break;
}
}
}
if(node->parent == NULL)
{
self->_root = node;
node->color = RBT_BLACK;
}
return true;
}
bool tree_rb_init(struct _tree *self, uint32_t obj_size)
{
assert(self != NULL);
self->_obj_size = obj_size;
self->_size = 0;
// self->_capacity = 64;
// self->_ratio = 2;
self->_right_priority = false;
self->insert = tree_avl_insert;
self->delete = tree_avl_delete;
self->clear = tree_clear;
self->empty = tree_empty;
self->size = tree_size;
self->destory = tree_destory;
self->preorder = tree_avl_preorder;
self->inorder = tree_avl_inorder;
self->postorder = tree_avl_postorder;
self->breadth = tree_avl_breadth;
self->order = tree_order;
self->find = tree_avl_find;
self->height = tree_height;
self->rebalance = tree_rb_rebalance;
self->find_max = tree_find_max;
self->find_min = tree_find_min;
self->max = tree_max;
self->min = tree_min;
self->_root = NULL;
return true;
}
tree_t tree_new(void)
{
return (struct _tree*)malloc(sizeof(struct _tree));
}
void tree_free(tree_t tree)
{
if(tree != NULL)
{
tree->destory(tree);
free(tree);
}
}