mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-07-03 23:56:54 +08:00
删除操作还存在问题
This commit is contained in:
parent
dca7598c51
commit
ccee58fda7
@ -104,8 +104,8 @@ struct _tree
|
|||||||
bool (*delete)(struct _tree* self, void* obj);
|
bool (*delete)(struct _tree* self, void* obj);
|
||||||
|
|
||||||
struct _tree_node* (*find)(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_min)(struct _tree* self, struct _tree_node* root);
|
||||||
struct _tree_node* (*find_max)(struct _tree* self);
|
struct _tree_node* (*find_max)(struct _tree* self, struct _tree_node* root);
|
||||||
|
|
||||||
bool (*rebalance)(struct _tree* self, struct _tree_node* root);
|
bool (*rebalance)(struct _tree* self, struct _tree_node* root);
|
||||||
uint32_t (*height)(struct _tree* self, struct _tree_node* root);
|
uint32_t (*height)(struct _tree* self, struct _tree_node* root);
|
||||||
|
99
src/tree.c
99
src/tree.c
@ -1695,41 +1695,72 @@ bool tree_avl_insert(struct _tree* self, void* obj)
|
|||||||
return true;
|
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)
|
||||||
|
{
|
||||||
|
self->_root = node->left != NULL ? node->left : node->right;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(node->parent->left == node)
|
||||||
|
{
|
||||||
|
node->left->parent = node->parent;
|
||||||
|
node->parent->left = node->left != NULL ? node->left : node->right;
|
||||||
|
}
|
||||||
|
else if(node->parent->right == node)
|
||||||
|
{
|
||||||
|
node->right->parent = node->parent;
|
||||||
|
node->parent->right = node->left != NULL ? node->left : node->right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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)
|
bool tree_avl_delete(struct _tree* self, void* obj)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
assert(obj != NULL);
|
assert(obj != NULL);
|
||||||
assert(self->compare != NULL);
|
assert(self->compare != NULL);
|
||||||
|
|
||||||
// if
|
|
||||||
if(self->empty(self))
|
if(self->empty(self))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
struct _tree_node* node = self->find(self, obj);
|
||||||
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
struct _tree_node* node = self->find(self, obj);
|
return false;
|
||||||
if(node == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(obj != NULL)
|
|
||||||
{
|
|
||||||
memmove(obj, node->obj, self->_obj_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node->parent->left == node)
|
|
||||||
{
|
|
||||||
node->parent->left = NULL;
|
|
||||||
}
|
|
||||||
else if(node->parent->right == node)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
tree_node_free(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(node->left != NULL && node->right != NULL)
|
||||||
|
{
|
||||||
|
tree_avl_delete_double_child(self, node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tree_avl_delete_single_child(self, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
tree_node_free(node);
|
||||||
self->_size--;
|
self->_size--;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1917,6 +1948,28 @@ void tree_avl_breadth(struct _tree* self, struct _tree_node* root)
|
|||||||
queue_free(queue);
|
queue_free(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct _tree_node* tree_find_min(struct _tree* self, struct _tree_node* root)
|
||||||
|
{
|
||||||
|
assert(self != NULL);
|
||||||
|
assert(root != NULL);
|
||||||
|
if(root->left == NULL)
|
||||||
|
{
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
return tree_find_min(self, root->left);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct _tree_node* tree_find_max(struct _tree* self, struct _tree_node* root)
|
||||||
|
{
|
||||||
|
assert(self != NULL);
|
||||||
|
assert(root != NULL);
|
||||||
|
if(root->right == NULL)
|
||||||
|
{
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
return tree_find_max(self, root->right);
|
||||||
|
}
|
||||||
|
|
||||||
bool tree_avl_init(struct _tree *self, uint32_t obj_size)
|
bool tree_avl_init(struct _tree *self, uint32_t obj_size)
|
||||||
{
|
{
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
@ -1942,6 +1995,8 @@ bool tree_avl_init(struct _tree *self, uint32_t obj_size)
|
|||||||
self->find = tree_avl_find;
|
self->find = tree_avl_find;
|
||||||
self->height = tree_height;
|
self->height = tree_height;
|
||||||
self->rebalance = tree_avl_rebalance;
|
self->rebalance = tree_avl_rebalance;
|
||||||
|
self->find_max = tree_find_max;
|
||||||
|
self->find_min = tree_find_min;
|
||||||
|
|
||||||
self->_root = NULL;
|
self->_root = NULL;
|
||||||
|
|
||||||
|
@ -10,10 +10,13 @@ int compare_num(void *obj, void *obj2)
|
|||||||
{
|
{
|
||||||
int num1 = *(int*)obj;
|
int num1 = *(int*)obj;
|
||||||
int num2 = *(int*)obj2;
|
int num2 = *(int*)obj2;
|
||||||
return num1 - num2 > 0 ? 1 : -1;
|
if(num1 == num2)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return num1 > num2 ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void print_struct(void* obj)
|
void print_struct(void* obj)
|
||||||
{
|
{
|
||||||
struct _student* student = (struct _student*)obj;
|
struct _student* student = (struct _student*)obj;
|
||||||
|
@ -331,17 +331,26 @@ void test_tree_num(void)
|
|||||||
tree->breadth(tree, tree->_root);
|
tree->breadth(tree, tree->_root);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
#if 0
|
for (i = 0; i < len; i++)
|
||||||
while(!tree->empty(tree))
|
|
||||||
{
|
{
|
||||||
|
temp = data[i];
|
||||||
tree->delete(tree, &temp);
|
tree->delete(tree, &temp);
|
||||||
|
|
||||||
printf("pop = ");
|
printf("delete = ");
|
||||||
tree->print_obj(&temp);
|
tree->print_obj(&temp);
|
||||||
|
|
||||||
printf("size = %2d\n", tree->size(tree));
|
printf("size = %2d\n", tree->size(tree));
|
||||||
|
|
||||||
|
printf("----- breadth -----\n");
|
||||||
|
tree->breadth(tree, tree->_root);
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
if(tree->empty(tree))
|
||||||
|
{
|
||||||
|
printf("----- empty -----\n");
|
||||||
|
}
|
||||||
|
|
||||||
tree_free(tree);
|
tree_free(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user